WCF調(diào)用服務異?;窘鉀Q方案介紹
在應用WCF工具進行實際開發(fā)的時候,通常都會遇到一些異常的發(fā)生。那么如何才能正確有效的處理這些異常的產(chǎn)生呢?在這里我們先來一起了解一下WCF調(diào)用服務異常的相關解決方法,以幫助大家解決問題。#t#
WCF調(diào)用服務異常主要包括以下三種類型:
1. 通訊異常。諸如網(wǎng)絡錯誤,地址錯誤,服務器沒有啟動等等。這類異常多是 CommunicationException (或其具體繼承類型)。
2. 狀態(tài)異常。比如訪問了已經(jīng)關閉的代理對象,契約錯誤,以及安全設置錯誤等。常見的有 ObjectDisposedException。
3. 服務異常。由服務器觸發(fā),多是 FaultException。
針對WCF調(diào)用服務異常,不同的實例管理方式會有不同的策略。
1. Pre-Call: 服務實例被釋放,客戶端拋出 FaultException,客戶端代理對象無法繼續(xù)使用。
2. Pre-Session: 服務實例被釋放,會話終止??蛻舳藪伋?FaultException,客戶端代理對象無法繼續(xù)使用。
3. Singleton: 服務實例依舊運行,會話終止??蛻舳藪伋?FaultException,客戶端代理對象無法繼續(xù)使用。
基于平臺中立和技術整合的需要,WCF 以標準 Soap Faults 方式傳遞異常信息。WCF 提供了 FaultException 和 FaultException<T> 兩個類型來操控 Soap Faults。通過 FaultException<T> 我們可以向客戶端傳遞一個錯誤信息(FaultReason)以及一個附加的詳細信息(Detail)。理論上,這個附加信息是任何可以序列化的對象。
- throw new FaultException<int>(123, "abc");
 - throw new FaultException<Exception>(new Exception("abc"));
 
如果想傳遞一個附帶元數(shù)據(jù)的自定義詳細信息,可以使用FaultContract。
- [DataContract]
 - public class ExceptionData
 - {
 - [DataMember]
 - public string Message;
 - }
 - [ServiceContract]
 - public interface IService
 - {
 - [OperationContract]
 - [FaultContract(typeof(ExceptionData))]
 - void Test();
 - }
 - public class Service : IService, IDisposable
 - {
 - public void Test()
 - {
 - ExceptionData d = new ExceptionData();
 - d.Message = "xxxxxx";
 - throw new FaultException<ExceptionData>(d, "abc");
 - }
 - public void Dispose()
 - {
 - Console.WriteLine("Dispose...");
 - }
 - }
 
當然,我們也可以直接拋出一個被稱之為 "Unknown Faults" 的 FaultException 異常實例。還有另外一種情況,你已經(jīng)寫好了代碼,有很多……很多……的代碼,要是一個個修改會非常……非常……麻煩,那么怎么在不做大的代碼修改情況下傳遞詳細異常信息給客戶端呢?
WCF調(diào)用服務異常方法1: ServiceBehavior(IncludeExceptionDetailInFaults=true)]
- [ServiceBehavior(IncludeExceptionDetailInFaults=true)]
 - public class Service : IService, IDisposable
 - {
 - public void Test()
 - {
 - throw new Exception("abc");
 - }
 - public void Dispose()
 - {
 - Console.WriteLine("Dispose...");
 - }
 - }
 
方法2: ServiceDebugBehavior
這個WCF調(diào)用服務異常的處理方法比方法1要更方便一些,我們除了可以寫代碼外,還可以用配置文件。
- ServiceHost host = new ServiceHost(typeof(Service),
 
new Uri("http://localhost:8080/Service"));- host.AddServiceEndpoint(typeof(IService),
 
new BasicHttpBinding(), "");- ServiceDebugBehavior debug = host.Description.Behaviors.
 
Find<ServiceDebugBehavior>();- debug.IncludeExceptionDetailInFaults = true;
 - host.Open();
 
看看這兩種方法拋出的異常是什么樣的。
未處理 System.ServiceModel.FaultException`1
Message="abc"
Source="mscorlib"
StackTrace:
Server stack trace:
在 ConsoleApplication1.localhost.IService.Test()
在 ConsoleApplication1.localhost.ServiceClient.Test() 位置 D:\...\localhost.cs:行號 60
在 ConsoleApplication1.Program.Main(String[] args) 位置 D:\...\Program.cs:行號 62
不錯,除了 Error Message,還有詳細的 stack trace,方便調(diào)試。也正因為這樣,此種方法也不適合在正式項目中使用,作為系統(tǒng)架構設計的一部分,我們應該事先設計好異常處理。
如果服務方法是 IsOneWay=true,因不接收返回消息,客戶端也就不會觸發(fā)異常了。而 Callback 無非是服務器和客戶端掉換個身份而已,道理相同。
- public interface ICallback
 - {
 - [OperationContract]
 - void DoCallback();
 - }
 - [ServiceContract(CallbackContract=typeof(ICallback))]
 - public interface IService
 - {
 - [OperationContract]
 - void Test();
 - }
 - [ServiceBehavior(ConcurrencyModeConcurrencyMode=
 
ConcurrencyMode.Reentrant)]- public class Service : IService, IDisposable
 - {
 - public void Test()
 - {
 - try
 - {
 - OperationContext.Current.GetCallbackChannel<ICallback>().
 
DoCallback();- }
 - catch (FaultException e)
 - {
 - Console.WriteLine(e);
 - }
 - }
 - public void Dispose()
 - {
 - Console.WriteLine("Dispose...");
 - }
 - }
 
以上就是我們?yōu)榇蠹医榻B的WCF調(diào)用服務異常的相關解決方法。















 
 
 


 
 
 
 