So basically I want to handle exceptions in WCF services in centralized place. For that I created a class that implements IErrorHandler
and a class that implements IServiceBehavior
and in that Service Behavior implementation I am saying that for each channel dispatcher I want to add my custom error handler like this.
public void ApplyDispatcherBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler = new CustomErrorHandler();
foreach (var channelDispatcher in serviceHostBase.ChannelDispatchers)
{
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
and the final thing that I've done is created a class that derives from a BehaviorExtensionElement
with appropriate implementation and registered the extension in config file. but it does not seem to work. I mean that thing I want to do is if exception stays unhandled I want to handle it somewhere in a centralized place. But it does not seem to work for me. Is my implementation correct, am I misunderstanding how this whole thing that I implemented should work. Any suggestion would be appreciated.
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<bindings>
<basicHttpBinding>
<binding name="soapBinding" />
</basicHttpBinding>
<webHttpBinding>
<binding name="webBinding" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="poxBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="MyCustomBehaviorExtensionElement" type="MyNamespace.CustomExtensionElement, MyNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="defaultBehavior">
<endpoint address="pox" binding="webHttpBinding" behaviorConfiguration="poxBehavior"
name="pox" contract="MyNamespace.IMyService" />
<endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="soapBinding"
name="soap" contract="MyNamespace.IMyService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/Services" />
</baseAddresses>
</host>
</service>
here is the part of config file
Missed in your web config
In your case you haven't applied your extension, you need to add to your service behaviour your extension:
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceMetadata httpGetEnabled="true" />
<MyCustomBehaviorExtensionElement />
</behavior>
</serviceBehaviors>
WebHttpBinding:
But, for handling error for WebHttpBinding you have to use such approach:
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using log4net;
namespace Server.Web
{
public class WebHttpWithErrorHandlingElement : BehaviorExtensionElement
{
public class WebHttpWithErrorHandlingBehavior : WebHttpBehavior
{
internal sealed class WebHttpErrorHandler : IErrorHandler
{
private static readonly ILog logger = LogManager.GetLogger(typeof (WebHttpErrorHandler));
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
var exception = new FaultException("Web Server error encountered. All details have been logged.");
var messageFault = exception.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, exception.Action);
}
public bool HandleError(Exception error)
{
logger.Error(string.Format("An error has occurred in the Web service {0}", error));
return !(error is FaultException);
}
}
protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
base.AddServerErrorHandlers(endpoint, endpointDispatcher);
endpointDispatcher.DispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(new WebHttpErrorHandler());
}
}
public WebHttpWithErrorHandlingElement()
{
}
public override Type BehaviorType
{
get { return typeof (WebHttpWithErrorHandlingBehavior); }
}
protected override object CreateBehavior()
{
return new WebHttpWithErrorHandlingBehavior();
}
}
}
Config file:
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="webHttpWhithErrorHanlding" type="Server.Web.WebHttpWithErrorHandlingElement, Server.Web"/>
</behaviorExtensions>
</extensions>
<!-- other staff -->
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttpWhithErrorHanlding />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
And then apply it to your endpoint:
<service name="YourServiceContract">
<endpoint address=""
binding="webHttpBinding"
behaviorConfiguration="webBehavior"
contract="IYourServiceContract"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost/"/>
</baseAddresses>
</host>
</service>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.