Tag Archives: Elmah

Catching Exceptions with Elmah within WCF

We all use the excellent ELMAH to deal with unhandled exceptions in an ASP.NET 3.5 web or MVC application. This works extremely well for all of the site, now what about WCF how can we get Elmah to work for us?

You can use the HttpHandler, and Decorate your Service(s) with an Error Handling attribute.

The ServiceErrorBehaviourAttribute:

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

/// <summary>
/// So we can decorate Services with the [ServiceErrorBehaviour(typeof(HttpErrorHandler))]
/// ...and errors reported to ELMAH
/// </summary>
public class ServiceErrorBehaviourAttribute : Attribute, IServiceBehavior
{
    readonly Type _errorHandlerType;

    public ServiceErrorBehaviourAttribute(Type errorHandlerType)
    {
        this._errorHandlerType = errorHandlerType;
    }

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

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

    public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
    {
        var errorHandler = (IErrorHandler)Activator.CreateInstance(_errorHandlerType);
        foreach (var channelDispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>())
        {
            channelDispatcher.ErrorHandlers.Add(errorHandler);
        }
    }
}

Now the HttpErrorHandler:

using Elmah;
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

/// <summary>
/// Your handler to actually tell ELMAH about the problem.
/// </summary>
public class HttpErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        return false;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        if (error == null) return;

        ErrorLog.GetDefault(null).Log(new Error(error));
    }
}

Now it is just a simple case of adding an attribute to the WCF Service:

[ServiceErrorBehaviour(typeof(HttpErrorHandler))]
public class Game : IGame
{

Here is a small sample application showing it in action

WcfService1.zip (8.26 kb)