程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 使用IErrorHandle對WCF服務器進行異常處理

使用IErrorHandle對WCF服務器進行異常處理

編輯:關於.NET

概述:

在實際的項目開發中,我們常常會處理各種各樣的異常,在代碼中不斷充斥著try{}catch{}finally{}語句塊,這些處理有些時候是不可缺少的,因為誰都沒有辦法保證自己寫的代碼無異常運行,外部環境造成了異常存在的可能性,但是我常常覺得,捕獲異常的語句塊經常把原本清晰的業務邏輯弄得七零八落的,當然,本篇的目的不是說異常捕獲可完全避免,但到少WCF可以讓我們稍微從異常處理中得到一點解脫。

1、首先來看常規的服務實現類在處理異常時的做法,下面是常規的捕獲了一個除數為0的異常。

常規異常捕獲

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

2、再看看應用了IErrorHandler接口來處理異常後的代碼。

public string Div(int x,int y)
     {
       return string.Format("{0}",x/y);
     }

有爽的感覺嗎?如果沒有,請仔細想想1000個方法中的異常處理。這就是WCF讓程序自己拋出異常並自行捕獲。

3、如何實現?

3.1、要達到上述的效果,我們需要自定義一類並實現IErrorHandler接口,代碼相當的簡單,如下:

public class FaultErrorHandler : IErrorHandler
   {
     #region IErrorHandler 成員
     public bool HandleError(Exception error)
     {
       // TO DO 在這裡可以做日志記錄等。
       Console.WriteLine("Message:{0},StackTrace:{1}",error.Message,error.StackTrace);
       return true;
     }
     public void ProvideFault(Exception error,MessageVersion version,ref Message fault)
     {
       FaultException fe = new FaultException(error.Message,FaultCode.CreateReceiverFaultCode(error.Source,error.StackTrace));
       MessageFault messagefault = fe.CreateMessageFault();
       fault = Message.CreateMessage(version,messagefault,"http://www.microsoft.com/");
     }
     #endregion
}

只有十來行代碼,相當於我們以前的創建日志文件代碼。

3.2、為了可復用性,我們希望所有的服務都可以使用上面的這段代碼,那麼我們就必須要創建一個可以在配置文件中注冊的服務配置類,也十分的簡單,如下:

public sealed class ServiceErrorBehavior : BehaviorExtensionElement,IServiceBehavior
   {
     public void Validate(ServiceDescription description,ServiceHostBase serviceHostBase) { return; }
     public void AddBindingParameters(ServiceDescription description,ServiceHostBase serviceHostBase,System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,BindingParameterCollection parameters) { return; }
     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 { get { return typeof(ServiceErrorBehavior); } }
     protected override object CreateBehavior() { return new ServiceErrorBehavior(); }
}

上面的代碼也是十來行而已,相當的簡單。這段代碼的意思是說:為了可以在配置文件中注冊一個配置,我實現了 BehaviorExtensionElement類,並重寫了BehaviorExtensionElement的BehaviorType屬性和 CreateBehavior方法,因為在服務啟動時,服務主機會自動的獲取BehaviorType類型和通過CreateBehavior方法創建一個擴展配置節點。實現的IServiceBehavior接口是為了在服務分發通道中添加自定的異常處理程序,這樣,在服務發生異常時WCF服務就可以通過這個配置節點找到相應的ErrorHandler處理程序,並自動調用。

4、在配置文件中注冊自定義的擴展配置節,我們所需要做的工作只是把下面的幾行代碼copy到app.config中,並將其放在system.serviceModel節點下。

<extensions>
    <behaviorExtensions>
     <add name="enforceGreetingFaults" type="Common.ServiceErrorBehavior,Common,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null" />
    </behaviorExtensions>
</extensions>

4.1、然後,再把上面的擴展配置加入到服務配置中,即把enforceGreetingFaults加入到這裡,綠色部分為上面的擴展節點名稱:

注冊擴展配置

<serviceBehaviors>
     <behavior name="WcfService.Service1Behavior">
      <serviceMetadata httpGetEnabled="false"/>
      <serviceDebug includeExceptionDetailInFaults="true" />
      <enforceGreetingFaults />
     </behavior>
    </serviceBehaviors>

5、最後客戶端一如既往的調用服務就OK了。

6、特別注意事項:在創建服務擴展節點也就是(behaviorExtensions)時,需要仔細檢查type="Common.ServiceErrorBehavior,Common,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"這一串,一定要記得“,”號後面要帶一個空格,切記是帶一個,既不能多也不能少,否則服務主機注冊失敗。

出處:http://www.cnblogs.com/viter/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved