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

WCF 服務異外處理最佳實踐:IErrorHandler 實現統一錯誤管理

     編輯:關於.NET

痛點:傳統 Try-Catch 污染業務邏輯

傳統 WCF 服務中,每個方法都需包裹 try-catch,導致業務代碼混雜異常處理邏輯,維護困難。本文展示如何用 IErrorHandler 實現集中式異常處理,讓服務代碼回歸純淨。

對比:處理前 vs 處理後

傳統寫法(冗餘)

public string Div(int x, int y)
{
    int result = 0;
    try
    {
        result = x / y;
    }
    catch (DivideByZeroException ex)
    {
        throw ex;
    }
    return string.Format("{0}", result);
}

引入 IErrorHandler 後(乾淨)

public string Div(int x, int y)
{
    return string.Format("{0}", x / y); // 直接拋出異常,由框架統一處理
}

核心實現步驟

1. 實現 IErrorHandler 介面

public class FaultErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        // 記錄日誌等橫切關注點
        Console.WriteLine("Message:{0}, StackTrace:{1}", error.Message, error.StackTrace);
        return true; // true 表示已處理,不再傳播
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        // 將異常轉為 SOAP Fault 回傳客戶端
        FaultException fe = new FaultException(
            error.Message,
            FaultCode.CreateReceiverFaultCode(error.Source, error.StackTrace)
        );
        MessageFault messageFault = fe.CreateMessageFault();
        fault = Message.CreateMessage(version, messageFault, "https://www.microsoft.com/");
    }
}

2. 創建服務行為擴展

public sealed class ServiceErrorBehavior : BehaviorExtensionElement, IServiceBehavior
{
    public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase) { }
    public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase,
        Collection endpoints, BindingParameterCollection parameters) { }

    public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
    {
        IErrorHandler errorHandler = new FaultErrorHandler();
        foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
        {
            ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
            channelDispatcher.ErrorHandlers.Add(errorHandler);
        }
    }

    public override Type BehaviorType => typeof(ServiceErrorBehavior);
    protected override object CreateBehavior() => new ServiceErrorBehavior();
}

3. 配置文件註冊

<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="enforceGreetingFaults" 
           type="Common.ServiceErrorBehavior, Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </behaviorExtensions>
  </extensions>
  
  <serviceBehaviors>
    <behavior name="WcfService.Service1Behavior">
      <serviceMetadata httpGetEnabled="false"/>
      <serviceDebug includeExceptionDetailInFaults="true" />
      <enforceGreetingFaults /> <!-- 關鍵:啟用自定義錯誤處理 -->
    </behavior>
  </serviceBehaviors>
</system.serviceModel>

關鍵注意事項

  • 型別字串格式:type="Namespace.Class, Assembly, Version=..., Culture=neutral, PublicKeyToken=null",逗號後必須有一個空格,否則服務啟動失敗
  • FaultContract 聲明:服務介面方法需標註 [FaultContract(typeof(YourFaultType))] 才能讓客戶端正確反序列化強型別異常
  • HandleError 返回值:返回 true 表示異常已處理不再傳播;false 會繼續向上拋出

總結

透過 IErrorHandler + 自定義 BehaviorExtensionElement,實現 WCF 異常處理的「橫切關注點」分離。服務代碼專注業務邏輯,異常記錄、轉換、回傳統一由框架層完成,大幅提升代碼可維護性與一致性。

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