*.DomainServices.HttpErrorHandler

Coordinator
Apr 23, 2012 at 9:52 PM

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

namespace Fox.DomainServices
{
    /// <summary>
    /// Defines an Error Handler to support ELMAH with WCF.
    /// </summary>
    /// <remarks>
    /// For more, see http://stackoverflow.com/questions/895901/exception-logging-for-wcf-services-using-elmah
    /// </remarks>
    public class HttpErrorHandler : IErrorHandler
    {
        /// <summary>
        /// Enables error-related processing and returns a value that indicates whether the dispatcher aborts the session and the instance context in certain cases.
        /// </summary>
        /// <param name="error">The exception thrown during processing.</param>
        /// <returns>
        /// true if  should not abort the session (if there is one) and instance context if the instance context is not <see cref="F:System.ServiceModel.InstanceContextMode.Single"/>; otherwise, false. The default is false.
        /// </returns>
        public bool HandleError(Exception error)
        {
            return false;
        }

        /// <summary>
        /// Enables the creation of a custom <see cref="T:System.ServiceModel.FaultException`1"/> that is returned from an exception in the course of a service method.
        /// </summary>
        /// <param name="error">The <see cref="T:System.Exception"/> object thrown in the course of the service operation.</param>
        /// <param name="version">The SOAP version of the message.</param>
        /// <param name="fault">The <see cref="T:System.ServiceModel.Channels.Message"/> object that is returned to the client, or service, in the duplex case.</param>
        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            if (error != null) // Notify ELMAH of the exception.
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(error);
            }
        }
    }

}

Coordinator
Apr 23, 2012 at 9:53 PM

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

namespace Fox.DomainServices
{
    /// <summary>
    /// Defines an <see cref="System.Attribute"/>
    /// to support ELMAH with a WCF Service.
    /// </summary>
    /// <remarks>
    /// We can decorate Services with the <c>[ServiceErrorBehaviour(typeof(HttpErrorHandler))]</c>
    /// and errors reported to ELMAH.
    /// For more, see http://stackoverflow.com/questions/895901/exception-logging-for-wcf-services-using-elmah
    /// </remarks>
    public class ServiceErrorBehaviorAttribute : Attribute, IServiceBehavior
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceErrorBehaviorAttribute"/> class.
        /// </summary>
        /// <param name="errorHandlerType">Type of the error handler.</param>
        public ServiceErrorBehaviorAttribute(Type errorHandlerType)
        {
            this.errorHandlerType = errorHandlerType;
        }

        /// <summary>
        /// Validates the specified description.
        /// </summary>
        /// <param name="description">The description.</param>
        /// <param name="serviceHostBase">The service host base.</param>
        public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
        }

        /// <summary>
        /// Adds the binding parameters.
        /// </summary>
        /// <param name="description">The description.</param>
        /// <param name="serviceHostBase">The service host base.</param>
        /// <param name="endpoints">The endpoints.</param>
        /// <param name="parameters">The parameters.</param>
        public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
        {
        }

        /// <summary>
        /// Applies the dispatch behavior.
        /// </summary>
        /// <param name="description">The description.</param>
        /// <param name="serviceHostBase">The service host base.</param>
        public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            IErrorHandler errorHandler;
            errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
                channelDispatcher.ErrorHandlers.Add(errorHandler);
            }
        }

        Type errorHandlerType;
    }
}