2008-09-17 108 views
37

我們目前正在辯論是否最好在WCF通道上拋出錯誤,而不是傳遞指示服務狀態或響應的消息。WCF - 故障/異常與消息

故障來自WCF的內置支持,您可以使用內置的錯誤處理程序並作出相應的反應。然而,這會帶來開銷,因爲在.NET中拋出異常可能會非常昂貴。

消息可以包含必要的信息,以確定發生了什麼事與您的服務調用沒有拋出異常的開銷。但是,它需要幾行重複代碼來分析消息並確定其內容後面的操作。

我們帶着刺創造,我們可以在我們的服務採用一個通用的消息對象,而這也正是我們提出了:

public class ReturnItemDTO<T> 
{ 
    [DataMember] 
    public bool Success { get; set; } 

    [DataMember] 
    public string ErrorMessage { get; set; } 

    [DataMember] 
    public T Item { get; set; } 
} 

如果我所有的服務調用返回這個項目,我可以持續檢查「成功」屬性來確定是否一切順利。然後我在事件中顯示錯誤消息字符串,表明出現了錯誤,並且如果需要,則會包含Dto的通用項目。

必須將異常信息記錄到中央日誌記錄服務,而不是從服務傳回。

想法?註釋?想法?建議?

一些進一步澄清我的問題

一個問題我在遇到故障時合同的通信業務規則。

像,如果有人登錄,並且他們的帳戶被鎖定,我該如何溝通?他們的登錄顯然失敗,但由於「賬戶鎖定」原因而失敗。

所以做我:

A)使用一個布爾值,拋出故障與消息帳戶鎖定

B)相關信息

回答

31

然而,這架空攜帶在拋出異常返回AuthenticatedDTO。 NET可能會相當昂貴。

您正在序列化和反序列化對象到XML並通過慢速網絡發送它們..與拋出異常相比,拋出異常的開銷可以忽略不計。

我平時堅持拋出異常,因爲他們清楚地傳達出了問題,所有 Web服務工具包有處理它們的好方法。

在你的示例中,我會拋出一個UnauthorizedAccessException與消息「賬戶鎖定」。

澄清:默認情況下,.NET wcf服務將異常轉換爲FaultContracts,但您可以更改此行爲。MSDN:Specifying and Handling Faults in Contracts and Services

+0

我不同意。由於WCF應該是語言不可知的(至少在某種形式中),你不能保證在線路上傳遞一個Exception對象不會導致buig問題。 Java客戶端。 FaultContract對象類型可以確保互操作性,因爲它是OASIS規範的一部分。 – ZombieSheep 2008-09-17 09:39:40

0

我會認真考慮使用FaultContract和的FaultException對象來解決這個問題。這將允許您將有意義的錯誤消息傳遞迴客戶端,但只有在出現故障時纔會發送。

不幸的是,我在目前的培訓課程,所以不能寫了一個完整的答案,但幸運的是我學習WCF中的應用程序異常管理。今晚我會回覆更多的信息。 (對不起,這是一個微弱的答案)

6

如果你想調用服務就像調用任何其他方法一樣,它可能有助於將事物置於透視之中。想象一下,如果你調用的每一種方法都返回一個狀態,那麼由你來決定它是真是假。它會變得非常乏味。

result = CallMethod(); 
if (!result.Success) handleError(); 

result = CallAnotherMethod(); 
if (!result.Success) handleError(); 

result = NotAgain(); 
if (!result.Success) handleError(); 

這是一個結構化的錯誤處理系統的優勢之一,是您可以在實際的邏輯從你的錯誤處理分開。您不必繼續檢查,如果沒有發生異常,則知道它是成功的。

try 
{ 
    CallMethod(); 
    CallAnotherMethod(); 
    NotAgain(); 
} 
catch (Exception e) 
{ 
    handleError(); 
} 

與此同時,通過返回結果,您將更多的責任放在客戶端上。您可能知道要檢查結果對象中的錯誤,但John Doe進來後只是開始打電話給您的服務,忘記因爲不拋出異常而導致任何錯誤。這是另一個例外的強大力量,當出現問題並需要照顧時,他們給了我們一個良好的面子。