2013-03-08 65 views
1

我似乎遇到了讓IErrorHandler接口工作的問題。我的代碼是WCF異常IErrorHandler沒有被調用

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Diagnostics; 
using System.ServiceModel; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Configuration; 
using System.ServiceModel.Description; 
using System.ServiceModel.Dispatcher; 

namespace WcfService3 
{ 
    public class Service1 : IService1 
    { 
     public string GetData(int value) 
     { 
      throw new Exception("asdf"); 

     } 
    } 

    public class MyErrorHandler : IErrorHandler 
    { 
     public MyErrorHandler() 
     { 
      string Hello = ""; 
     } 
     public bool HandleError(Exception error) 
     { 
      return true; 
     } 

     public void ProvideFault(Exception error, MessageVersion version, ref Message msg) 
     { 
      var vfc = new MyFault(); 
      var fe = new FaultException<MyFault>(vfc); 
      var fault = fe.CreateMessageFault(); 
      msg = Message.CreateMessage(version, fault, "http://ns"); 
     } 
    } 

    public class ErrorHandlerExtension : BehaviorExtensionElement, IServiceBehavior 
    { 
     public override Type BehaviorType 
     { 
      get { return GetType(); } 
     } 

     protected override object CreateBehavior() 
     { 
      return this; 
     } 

     private IErrorHandler GetInstance() 
     { 
      return new MyErrorHandler(); 
     } 

     void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) 
     { 
     } 

     void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
     { 
      IErrorHandler errorHandlerInstance = GetInstance(); 
      foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) 
      { 
       dispatcher.ErrorHandlers.Add(errorHandlerInstance); 
      } 
     } 

     void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
     { 
      foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints) 
      { 
       if (endpoint.Contract.Name.Equals("IMetadataExchange") && 
        endpoint.Contract.Namespace.Equals("http://schemas.microsoft.com/2006/04/mex")) 
        continue; 

       foreach (OperationDescription description in endpoint.Contract.Operations) 
       { 
        if (description.Faults.Count == 0) 
        { 
         throw new InvalidOperationException("FaultContractAttribute not found on this method"); 
        } 
       } 
      } 
     } 
    } 
} 

我的web.config是:

<?xml version="1.0"?> 
<configuration> 

    <appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
    </appSettings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5" /> 
    <httpRuntime targetFramework="4.5"/> 
    </system.web> 
    <system.serviceModel> 
     <services> 
    <service name="WcfService3.Service1"> 
     <endpoint address="" 
       binding="basicHttpBinding" 
       contract="WcfService3.IService1" /> 
    </service> 
    </services> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <!-- To avoid disclosing metadata information, set the values below to false before deployment --> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
     <extensions> 
    <behaviorExtensions> 
     <add name="errorHandler" 
      type="WcfService3.ErrorHandlerExtension, WcfService3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
    </extensions> 

    <protocolMapping> 
     <add binding="basicHttpsBinding" scheme="https" /> 
    </protocolMapping>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <!-- 
     To browse web app root directory during debugging, set the value below to true. 
     Set to false before deployment to avoid disclosing web app folder information. 
     --> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 

</configuration> 

我的WCF接口:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.Text; 

namespace WcfService3 
{ 
    [ServiceContract] 
    public interface IService1 
    { 
     [OperationContract] 
     [FaultContract(typeof(MyFault))] 
     string GetData(int value); 
    } 

    [DataContract] 
    public class MyFault 
    { 

    } 

} 

我的問題是在IErrorHandler在WCF中,如果在任何異常WCF服務調用,HandlerError()函數是假設首先調用像C#窗口應用程序UnhandledException類,然後服務應該崩潰的權利?在上面的代碼中,在服務調用期間拋出異常,但在拋出異常之前,我的HandlerError函數沒有被調用?我的目標是記錄錯誤,並且WCF服務可以拋出未處理的異常並崩潰。我期待在調試過程中斷點將訪問HandleError函數,但該函數沒有被調用,只是出現異常?

回答

2

您是否錯過了<errorHandler />在您的behavior欄目?

<behavior> 
    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
    <serviceDebug includeExceptionDetailInFaults="false"/> 
    <!-- HERE --> 
    <errorHandler /> 
    <!-- HERE --> 
</behavior> 

完整答案是here。加1回答。