1

WCFルーターで例外を処理する方法を見つけようとしています。これは、何らかの理由でルーターがプライマリエンドポイント(ここでは、EndpointNotFoundException、ServerTooBusyException、またはCommunicationObjectFaultedExceptionがあります)にメッセージを送信できず、バックアップリストからエンドポイントを選択することを意味します。このメッセージをバックアップエンドポイントに送信します。ルーターサービスでこの内部例外を取得するにはどうすればよいですか?この時点で、メモリ内のルータ設定を動的に変更し、バックアップエンドポイントをプライマリエンドポイントに変更したいためです。IErrorHandlerでこれを行うことは可能ですか?または、このカスタムフィルターを実行することは可能ですか?カスタムフィルターを使用してバックアップ動作を変更するにはどうすればよいですか?

4

1 に答える 1

0

これは、IErrorHandlerfowcfサービスを実装するための完全に機能する例です。これを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メソッドでは、この例外を適切な方法で処理できます。

于 2012-12-08T14:12:23.683 に答える