简体   繁体   English

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

[英]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. 如果我能完成这项工作,那么显然是在服务层中包装大量代码的一种很好的方法,将异常包装在服务层的Faults中。

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. 但是,尽管定义该属性的代码可以很好地编译并被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) 我还借用并砍掉了rorys网站上在CodePlex上找到的一段代码,以简化此问题而不更改其功能(删除了冗余重载)

this is driving me insane ... please help! 这让我发疯...请帮助! :D :D

Rory Primrose - attribute implementation Rory Primrose-属性实现

Rory Primrose - IErrorHandlerImplementation 罗里·报春花-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: 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); 
    }
}

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

It's very hard to help you out here because you haven't provided any information about what is happening in your application. 在这里很难为您提供帮助,因为您尚未提供有关应用程序中正在发生的事情的任何信息。

  • Why is it not working? 为什么不起作用?
  • What is happening (expected vs actual behavior/outcomes)? 发生了什么(预期与实际行为/结果)?
  • What exceptions do you get on your client? 您的客户有什么例外?
  • Do you have tracing set up? 您有跟踪设置吗?
  • Is there anything in the event log 事件日志中是否有任何内容
  • What's your WCF hosting scenario (winforms, windows service, IIS, casini)? 您的WCF托管方案是什么(winforms,windows服务,IIS,casini)?
  • Have you put breakpoints in the error handler? 您是否在错误处理程序中放置了断点?
  • What does your code look like? 您的代码是什么样的?
  • What does your config look like? 您的配置是什么样的?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM