使用WCF中的类级别属性实现IErrorHandler

时间:2010-07-05 10:01:09

标签: .net wcf attributes ierrorhandler iservicebehaviors

通过配置文件使其工作没有运气,因此决定尝试通过类级别属性进行更健壮的路由。如果我能够实现这一点,那么显然是一种很好的方法,可以在服务层中的Faults中包含异常,而无需使用大量代码。

然而,属性中的代码似乎永远不会运行 - 尽管代码定义了属性编译得非常好并且被IDE识别。我已经用完了解决这个问题的事情 - 这个例外只是为了处理而被抛出。

我还借用并删除了在rorys网站上的CodePlex上找到的一段代码,以便在不改变其功能的情况下简化此问题(删除冗余重载)

这让我疯了......请帮忙! :d

Rory Primrose - attribute implementation

Rory Primrose - IErrorHandlerImplementation

代码:

服务界面和实施

[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实现:

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); 
    }
}

属性定义 - 怀疑问题在这里。我很确定这是我如何使用这段代码。

   [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)
            {
                throw 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;
        }
    }

1 个答案:

答案 0 :(得分:0)

很难在这里帮助你,因为你没有提供有关你的申请中发生的事情的任何信息。

  • 为什么不工作?
  • 发生了什么(预期与实际行为/结果)?
  • 您对客户有什么例外?
  • 您是否设置了跟踪?
  • 事件日志中是否有任何内容
  • 您的WCF托管方案是什么(winforms,Windows服务,IIS,casini)?
  • 您是否在错误处理程序中添加了断点?
  • 您的代码是什么样的?
  • 您的配置是什么样的?