WCF Extensions: Error Handler

Posted on November 18, 2010 by

0


Overview

WCF allows developers to control the fault message returned to a caller of a Wcf service and optionally perform custom error processing such as logging. For that, WCF provides extension for error handler components. Error handlers are types that implement IErrorHandler interface and are associated with the service behavior. For now, the client side does not provide the same IErrorHandler-like interface as the service side.

In this post, we will take a look at an example on how to add a custom error handler to your Wcf service:

Sample Error Handler

First, lets see the IErrorHandler interface:

public interface IErrorHandler
{
    void ProvideFault(Exception error, MessageVersion version, ref Message fault);
    bool HandleError(Exception error);
}

As you can see it contains two methods:

  1. HandleError() – Used to implement error-related behaviors such as error logging, system notifications, shutting down the application, and so on, and return a value that specifies whether the exception has been handled appropriately.
  2. ProvideFault(Exception error, MessageVersion version, ref Message fault) – Creates a custom fault message that is returned to the client.

Now lets write our own error handler that does something with the exception we are getting:

class MyErrorHandler : IErrorHandler
{
   public bool HandleError(Exception error)
   {
       // Do some logging, system notifications, shutting down the application or whatever...
       // Returning true indicates you performed your behavior
       return true;
   }

   public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
   {
       Console.WriteLine(
           "Inside ProvideFault: Converting Exception status code to Forbidden for InvalidOperationException..");

       var exception = error as InvalidOperationException;
       if (exception != null)
       {
           WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
           WebOperationContext.Current.OutgoingResponse.StatusDescription = "StatusCode is set to Forbidden";
       }
   }
}

 
After we have our error handler ready, we need to associate it with a service behavior and add it per channel dispatcher:
 
class ErrorHandlerServiceBehavior : IServiceBehavior
{
   public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
   {
   }

   public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
   {
       foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
       {
           dispatcher.ErrorHandlers.Add(new MyErrorHandler());
       }
   }

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

 
We are almost done, we just need to add this behavior to the service host 
and we are set to go:
 
class ErrorHandlerExample
{
   static void Main(string[] args)
   {
       var serviceHost = new ServiceHost(singletonInstance);
       serviceHost.Description.Behaviors.Add(new ErrorHandlerServiceBehavior());
   }
}

 
And that is it!
Advertisements
Posted in: WCF Extensions