2012-07-13 71 views
1

我有一个双工WCF服务,我试图创建一个全局异常处理程序。IErrorHandler实现不处理异常

我创建了一个行为扩展为IErrorHandler实现按this blog post

如果我把一个断点在ApplyDispatchBehavior方法我可以看到我的处理程序被添加到该通道调度ErrorHandlers的财产,但如果我后来扔异常既不调用HandleError也不提供ProvideFault方法。

我的错误处理程序是这样的:

internal class ControlFrameworkErrorHandler : IErrorHandler, IServiceBehavior 
{ 
    private static readonly ILog Logger = LogManager.GetLogger(typeof(ControlFrameworkWcfService)); 


    public bool HandleError(Exception error) 
    { 
     Logger.Fatal("An unhandled exception occurred:"); 
     Logger.Fatal(error.Message); 
     Logger.Fatal(error.StackTrace); 
     return true; 
    } 

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
    } 

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
    } 

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

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     IErrorHandler errorHandler = new ControlFrameworkErrorHandler(); 

     foreach (var channelDispatcherBase in serviceHostBase.ChannelDispatchers) 
     { 
      var channelDispatcher = channelDispatcherBase as ChannelDispatcher; 
      if (channelDispatcher != null) 
      { 
       channelDispatcher.ErrorHandlers.Add(errorHandler); 
      } 
     } 
    } 
} 

我的行为实施看起来是这样的:

internal class ControlFrameworkErrorHandlerElement : BehaviorExtensionElement 
{ 
    public override Type BehaviorType 
    { 
     get 
     { 
      return typeof(ControlFrameworkErrorHandler); 
     } 
    } 

    protected override object CreateBehavior() 
    { 
     return new ControlFrameworkErrorHandler(); 
    } 
} 

而且我的App.config是这样的:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.serviceModel> 
     <services> 
      <service name="ControlFrameworkService.ControlFrameworkWcfService" behaviorConfiguration="ControlFrameworkServiceBehavior"> 
      <host> 
      <baseAddresses> 
       <add baseAddress="http://localhost:8080/ControlFrameworkService/service" /> 
      </baseAddresses> 
      </host> 
     <endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IControlFrameworkDuplex" contract="ControlFrameworkService.IControlFrameworkDuplex" /> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <bindings> 
     <wsDualHttpBinding> 
     <binding name="WSDualHttpBinding_IControlFrameworkDuplex" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="24.20:31:23.6470000" sendTimeout="24.20:31:23.6470000" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="8388608" maxReceivedMessageSize="2147483647" messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true" clientBaseAddress="http://localhost:808/myClient/"> 
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="8388608" maxBytesPerRead="8388608" maxNameTableCharCount="8388608" /> 
      <reliableSession ordered="true" inactivityTimeout="24.20:31:23.6470000" /> 
      <security mode="None"> 
      <message clientCredentialType="None" /> 
      </security> 
     </binding> 
     </wsDualHttpBinding> 
    </bindings> 
    <extensions> 
     <behaviorExtensions> 
     <add name="ControlFrameworkErrorHandler" type="ControlFrameworkService.ControlFrameworkErrorHandlerElement, ControlFrameworkService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
     </behaviorExtensions> 
    </extensions> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="ControlFrameworkServiceBehavior"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="True" /> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647" /> 
      <ControlFrameworkErrorHandler /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
    <system.diagnostics> 
     <trace autoflush="true"> 
     </trace> 
     <sources> 
     <source name="System.ServiceModel" switchValue="Information, ActivityTracing"  propagateActivity="true"> 
      <listeners> 
      <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="WcfDetailTrace.svclog" /> 
      </listeners> 
     </source> 
     </sources> 
    </system.diagnostics> 
</configuration> 
+0

您可能会将'channelDispatcher.ErrorHandlers.Add(errorHandler);'从其外观改为'channelDispatcher.ErrorHandlers.Add(this);',因为您的行为元素已经创建了错误处理程序的实例,并且将其添加到channeldispatchers的代码正在错误处理程序中运行。 – 2013-01-20 01:08:47

回答

1

你应该将HandleError方法中的代码移至ProvideFault方法。出于某种原因,即使文档说应该使用HandleError,但似乎并非如此。我遇到了同样的问题,我使用ProvideFault方法解决了这个问题。

我已经读过一些其他人在Interwebs上建议同样的事情。

如果别人有更好的主意,我是全部耳朵。