【问题标题】:How can I change the WCF Router Backup List Behavior with Custom Filter?如何使用自定义筛选器更改 WCF 路由器备份列表行为?
【发布时间】:2023-04-09 10:26:01
【问题描述】:

我正在尝试找到一种方法来处理 WCF 路由器中的异常,这意味着当由于任何原因路由器无法向主端点发送消息时(这里有 EndpointNotFoundException、ServerTooBusyException 或 CommunicationObjectFaultedException)并选择一个端点从备份列表中并将此消息发送到备份端点。如何在路由器服务中获取此内部异常?因为此时我想在内存中动态更改路由器配置,并用主端点更改备份端点。是否可以使用 IErrorHandler 执行此操作?还是可以做这个自定义过滤器?如何使用自定义过滤器更改备份行为?

【问题讨论】:

    标签: wcf wcf-routing


    【解决方案1】:

    这是实现 IErrorHandler fo wcf 服务的完整工作示例。我们可以为 WCF 路由器实现这一点,并在路由器级别获取内部异常,然后决定如何在运行时更改配置。

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [FaultContract(typeof(MyFault))]
        string GetData(int value);
    }
    
    [DataContract]
    public class MyFault
    {
    
    }
    
    public class Service1 : IService1
    {
        public string GetData(int value)
        {
            throw new Exception("error");
        }
    }
    
    public class MyErrorHandler : IErrorHandler
    {
         public bool HandleError(Exception error)
         {
             return true;
         }
    
         public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
         {
             var vfc = new MyFault();
             var fe = new FaultException<MyFault>(vfc);
             var fault = fe.CreateMessageFault();
             msg = Message.CreateMessage(version, fault, "http://ns");
         }
    }
    
    public class ErrorHandlerExtension : BehaviorExtensionElement, IServiceBehavior
    {
         public override Type BehaviorType
         {
             get { return GetType(); }
         }
    
         protected override object CreateBehavior()
         {
             return this;
         }
    
         private IErrorHandler GetInstance()
         {
             return new MyErrorHandler();
         }
    
         void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription,      ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
    
        }
    
        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            IErrorHandler errorHandlerInstance = GetInstance();
            foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(errorHandlerInstance);
            }
        }
    
        void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
            {
                if (endpoint.Contract.Name.Equals("IMetadataExchange") &&         endpoint.Contract.Namespace.Equals("http://schemas.microsoft.com/2006/04/mex"))
                    continue;
    
                foreach (OperationDescription description in endpoint.Contract.Operations)
                {
                     if (description.Faults.Count == 0)
                     {
                         throw new InvalidOperationException("FaultContractAttribute not found on this method");
                     }
                }
            }
        }
    }
    

    web.config:

     <system.serviceModel>
         <services>
             <service name="ToDD.Service1">
                 <endpoint address="" binding="basicHttpBinding" contract="ToDD.IService1" />
             </service>
         </services>
    
         <behaviors>
             <serviceBehaviors>
                 <behavior>
                     <serviceMetadata httpGetEnabled="true"/>
                     <serviceDebug includeExceptionDetailInFaults="false"/>
                     <errorHandler />
                 </behavior>
             </serviceBehaviors>
         </behaviors>
    
         <extensions>
             <behaviorExtensions>
                 <add name="errorHandler" type="ToDD.ErrorHandlerExtension, ToDD, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
             </behaviorExtensions>
         </extensions>
    </system.serviceModel>
    

    所以在 HandleError 方法中我们可以用适当的方式处理这个异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-07
      • 2020-02-03
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多