开发者

Implementing IErrorHandler using class level Attributes in WCF

Had no luck with getting it working via config files, so decided to attempt to go the more robust route of doign it via class level attributes. If I can get this working it is clearly a great way of wrapping exceptions in Faults in the service layer withou trepeating lots of code.

However the code in the attribute never seems to get run - despite the code that defines the attribute compiling perfectly well and being recognised by the IDE. I have ran out of things to read regarding solving this - the exception just to be handled and just gets thrown.

I have also borrowed and chopped down a piece of code found on CodePlex that is on rorys site to simplify it for this problem without changing its function (removed redundant overloads)

this is driving me insane ... please help! :D

Rory Primrose - attribute implementation

Rory Primrose - IErrorHandlerImplementation

The code:

The Service interface and implementation

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [FaultContract(typeof(FaultException))]
    string GetData(int value);
}

[ErrorHandler(typeof(KnownErrorHandler))]
public class Service1 : IService1
{
    public string GetData(int value)
    {
        throw new Exception("This exception should get handled.");
    }
}

KnownErrorHandler Implementation:

public class KnownErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        Trace.WriteLine(error.ToString());  
       return true;  
    }

    public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
    {
        FaultException faultException = new FaultException("Server error encountered. All details have been logged.");  
         MessageFault messageFault = faultException.CreateMessageFault();  
         fault = Message.CreateMessage(version, messageFault, faultException.Action); 
    }
}

Attribute definition - doubt the problem is here. I am fairly sure it is in how i am using this piece of code.

   [AttributeUsage(AttributeTargets.Class)]
    public sealed class ErrorHandler : Attribute, IServiceBehavior
    { 
        public ErrorHandler(Type errorHandler)
        {
            if (errorHandler == null)
            {throw new ArgumentNullException("errorHandler");}
            Type[] errorHandlerTypes = new[] { errorHandler };
            Initialize(errorHandlerTypes);
        }   

        public void AddBindingParameters(
            ServiceDescription serviceDescription,
            ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints,
            BindingParameterCollection bindingParameters)
        {
            // Nothing to do here
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            if (serviceHostBase == null)
            {
                t开发者_如何学JAVAhrow new ArgumentNullException("serviceHostBase");
            }

            // Loop through each channel dispatcher
            for (Int32 dispatcherIndex = 0; dispatcherIndex < serviceHostBase.ChannelDispatchers.Count; dispatcherIndex++)
            {
                // Get the dispatcher for this index and cast to the type we are after
                ChannelDispatcher dispatcher = (ChannelDispatcher)serviceHostBase.ChannelDispatchers[dispatcherIndex];

                // Loop through each error handler
                for (Int32 typeIndex = 0; typeIndex < ErrorHandlerTypes.Count; typeIndex++)
                {
                    Type errorHandlerType = ErrorHandlerTypes[typeIndex];

                    // Create a new error handler instance
                    IErrorHandler handler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);

                    // Add the handler to the dispatcher
                    dispatcher.ErrorHandlers.Add(handler);
                }
            }
        }

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


        private void Initialize(Type[] errorHandlerTypes)
        {
            const String ErrorHandlerTypesParameterName = "errorHandlerTypes";

            if (errorHandlerTypes == null)
            {
                throw new ArgumentNullException(ErrorHandlerTypesParameterName);
            }

            if (errorHandlerTypes.Length == 0)
            {
                throw new ArgumentOutOfRangeException(ErrorHandlerTypesParameterName);
            }

            List<String> typeNames = new List<String>(errorHandlerTypes.Length);

            // Loop through each item supplied
            for (Int32 index = 0; index < errorHandlerTypes.Length; index++)
            {
                Type errorHandlerType = errorHandlerTypes[index];

                // Check if the item supplied is null
                if (errorHandlerType == null)
                {
                    throw new ArgumentNullException(ErrorHandlerTypesParameterName);
                }

                // Check if the type doesn't define the IErrorHandler interface
                if (typeof(IErrorHandler).IsAssignableFrom(errorHandlerType) == false)
                {
                    // We can't use this type
                    throw new InvalidCastException();
                }

                String assemblyQualifiedName = errorHandlerType.AssemblyQualifiedName;

                if (typeNames.Contains(assemblyQualifiedName) == false)
                {
                    typeNames.Add(assemblyQualifiedName);
                }
                else
                {
                    throw new ArgumentException(
                        String.Format(CultureInfo.CurrentCulture, "Duplicate ErrorType Provided", assemblyQualifiedName));
                }
            }

            // Store the types
            ErrorHandlerTypes = new ReadOnlyCollection<Type>(errorHandlerTypes);
        }

        /// <summary>
        /// Gets the error handler types.
        /// </summary>
        /// <value>
        /// The error handler types.
        /// </value>
        public ReadOnlyCollection<Type> ErrorHandlerTypes
        {
            get;
            private set;
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜