首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 分散式開發步步為贏 (15):錯誤契約 FaultContract 與異常處理完整指南

     編輯:關於.NET

前言

分散式系統中,服務端異常如何正確傳遞至客戶端是核心課題。WCF 採用 SOAP Fault 機制,透過 FaultContract 與 FaultException<T> 實現強型別錯誤傳遞,避免通道錯誤導致 Proxy 失效。

1. .NET 異常處理回顧

CLR 異常模型特性:跨語言、跨進程、跨機器;優於返回碼檢查;使用 try/catch/finally 結構;throw 拋出異常物件。

2. WCF 異常處理機制

2.1 三類常見錯誤

  1. 通訊異常:網路、通道層面錯誤 → CommunicationException
  2. Proxy/Channel 狀態錯誤:通道已關閉、Faulted、逾時、安全驗證失敗
  3. 服務呼叫異常:業務邏輯拋出的異常,經序列化傳遞至客戶端 → 本文重點

2.2 FaultException 核心角色

WCF 將無法識別的 .NET 異常統一包裝為 FaultException(可序列化),客戶端可捕獲 FaultException 或基類 CommunicationException。泛型版本 FaultException<TDetail> 允許攜帶自訂錯誤資料型別 TDetail。

3. 錯誤契約 FaultContract

屬 WCF 四大契約之一。裝飾於 OperationContract,聲明該操作可能拋出的強型別 SOAP Fault:

[ServiceContract]
public interface IWCFService {
    [OperationContract]
    [FaultContract(typeof(OverflowException))]
    string SayHello(string name);
}

若未標註 FaultContract,服務拋出的 FaultException<OverflowException> 會被視為未宣告 Fault,導致通道進入 Faulted 狀態。

4. 進階擴展:IErrorHandler

實作 System.ServiceModel.Dispatcher.IErrorHandler 可攔截未處理異常:

  • ProvideFault:將任意異常轉換為 FaultException<T>(異常提升)
  • HandleError:記錄日誌、監控告警

透過 IServiceBehavior.ApplyDispatchBehavior 掛載至分發器。

5. 完整範例代碼

5.1 服務端

[ServiceContract(Namespace = "https://www.cnblogs.com/frank_xl/")]
public interface IWCFService {
    [OperationContract]
    [FaultContract(typeof(OverflowException))]
    string SayHello(string name);

    [OperationContract]
    [FaultContract(typeof(OverflowException))]
    string SayGoodBye(string name);
}

public class WCFService : IWCFService {
    public string SayHello(string name) {
        if (name.Length < 10) {
            Console.WriteLine("Hello! {0}...", name);
            return "Hello! " + name;
        }
        throw new FaultException<OverflowException>(new OverflowException(), "name Length is more than 10");
    }
    // SayGoodBye 同理
}

5.2 宿主

static void Main() {
    using (ServiceHost host = new ServiceHost(typeof(WCFService))) {
        host.Open();
        Console.WriteLine("Host running at {0}", host.State);
        foreach (var se in host.Description.Endpoints)
            Console.WriteLine("Listening at {0}", se.Address.Uri);
        Console.Read();
    }
}

5.3 客戶端

var proxy = new WCFServiceClient("WSHttpBinding_IWCFService");
try {
    Console.WriteLine(proxy.SayHello("Frank Xu"));           // 正常
    Console.WriteLine(proxy.SayHello("Frank Xu Lei WSHttpBinding")); // 觸發 Fault
}
catch (FaultException<OverflowException> oe) {
    Console.WriteLine("Fault: " + oe.Message);
}
catch (CommunicationException ce) {
    Console.WriteLine("Comm: " + ce.Message);
}
finally { proxy.Close(); }

5.4 執行結果

客戶端捕獲 FaultException 輸出

6. 關鍵注意事項

  1. 未加 FaultContract 或拋出非 FaultException,客戶端仍可收到異常,但通道會 Faulted。
  2. ServiceBehavior.IncludeExceptionDetailInFaults=true 可讓客戶端捕獲詳細 .NET 異常,但生產環境嚴禁開啟(資安與效能風險)。
  3. 異常對 Instance 生命週期影響取決於 InstanceContextMode:PerCall/PerSession 釋放實例,Single 則保留。

總結

掌握 FaultContract + FaultException<T> 模式,是建構健壯 WCF 服務的基石。配合 IErrorHandler 實現集中式錯誤處理與日誌記錄,可大幅提升系統可維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved