2009-10-08 77 views
23

我在兩臺或多臺遠程計算機上部署了WCF服務,並且有一個基於桌面的應用程序供客戶端用於訪問任何wcf服務。在WCF服務中處理異常的最佳方法是什麼?

WCF服務連接到SQL Server 2005以讀取和寫入數據。 這是客戶端應該位於同一個域中的Intranet方案。

現在可以有場景中WCF服務拋出異常:

  1. 無效的URL
  2. WCF服務關閉
  3. SQL Server 2005是沒有運行
  4. 客戶是不是在同一個域
  5. 驗證失敗
  6. 授權失敗

和許多其他例外。

對於每個異常,我必須執行一些操作或更新狀態欄,具體取決於例外情況。例如,如果授權失敗,我必須提示用戶重新輸入他們的憑證。

請提出最佳設計方法來處理此問題。

回答

32

您絕對可以捕獲並處理髮生在您的服務類上的所有異常,並將它們轉換爲FaultException或FaultException異常。

這樣,您不會「錯誤」(或推倒)您的客戶端和服務器之間的通信通道。

更好的方法是在服務類上實現接口IErrorHandler,該接口提供了一種全局捕獲所有異常的方法,並提供FaultException,而不是SOAPException。

你甚至可以將你的IErrorHandler變成一個可配置的行爲,可以在config中打開或關閉。

請參閱以下文章和博客文章的詳細信息:

+1

我不知道很多關於IErrorHandler但我讀文章和使用IErrorHandler的帖子說它有一些缺點。在某些情況下,可能會直接從wcf服務向客戶端拋出異常。你會推薦我IErrorHandler? – 2009-10-08 08:55:13

+0

是的,無論如何 - 我會**總是推薦使用IErrorHandler。你可以發佈鏈接到這些文章,說它有缺點?從來沒有聽說過這些 - 我想調查.... – 2009-10-08 08:56:24

+0

http://stackoverflow.com/questions/265551/wcf-errorhandler 閱讀第二篇文章!我不知道它是否正確,但它總是在我心中造成困惑 – 2009-10-08 09:01:28

2

您可以爲WCF服務中的每個異常情況設計特定的故障數據合同,以便您可以分別處理客戶端的故障/異常。

+0

我是新來的它,你可以請給我一些鏈接 – 2009-10-08 08:25:33

1
try 
{ 
    // Actions 
} 
catch (Exception ex) 
{ 
    // Log the exception 
    // Throw Fault Exception back to client 
    FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code")); 
    //throw fault exception back to WCF client 
    throw fe; 
}   
6
  1. 創建標有DataContract屬性
  2. 馬克自定義錯誤類方法關於服務與FaultContract合同界面。 IE瀏覽器。[FaultContract(typeof(CustomFault))]
  3. 在您的服務方法中,捕獲任何適用的內部異常並拋出FaultException<CustomFault>。或者,如marc_s所述,您可以使用IErrorHandler將異常映射到故障。

就我個人而言,我創建了一個具有Reason屬性的基本Fault類,並且擴展了此類中的所有自定義故障。當我要扔的錯,我呼籲:

throw Fault.Create<CustomFault>(new CustomFault("Boo hoo")); 

這也是值得注意的是,我的版本是我的錯類(包括常見的故障類)與我的所有其他服務一起。但是,如果服務版本控制是一個問題,這只是一個問題。

這裏是基本的故障類(我已經刪除了簡潔參數驗證):

[DataContract(Namespace = XmlVersionNamespace.FaultNamespace)] 
public abstract class Fault 
{ 
    internal FaultReason Reason { get; set; } 

    protected Fault(string reasonText) 
    { 
     Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture)); 
    } 

    public override string ToString() 
    { 
     return Reason.ToString(); 
    } 

    internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault 
    { 
     return new FaultException<TDetail>(fault, fault.Reason); 
    } 
} 
+0

謝謝理查!如果認證失敗,請給我一個例子。只要給我班級關係船和你將如何處理客戶端應用程序.. – 2009-10-08 08:57:13

+0

我會創建一個AuthenticationFailedFault(從故障擴展它),將消息傳遞給基礎Fault構造函數。在您的客戶端應用程序中,您只需捕獲FaultException ,因爲AuthenticationFailedFault將成爲WSDL的一部分(只要您使用[FaultContract]標記該方法) – 2009-10-08 10:09:53

相關問題