繁体   English   中英

客户端 WCF 异常处理程序

[英]Client-side WCF ExceptionHandler

是否可以使用 BehaviorExtension 在客户端处理 TimeoutException、EndpointNotFoundException、OperationTimeoutException 等错误?

我不想每次使用 WCF 代理时都尝试捕获日志重新启动连接。

此代码不起作用:

行为:

public class EndpointBehavior:IEndpointBehavior
{
    public void Validate(ServiceEndpoint endpoint)
    {

    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {


    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        var handler = new WcfErrorHandler();
        clientRuntime.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(handler);
    }
}

处理程序:

public class WcfErrorHandler:IErrorHandler
{
    public bool HandleError(Exception error)
    {
        Log.Instance.Trace(@"WCF Service Error:", error);
        return true;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        var newEx = new FaultException(
           string.Format(@"Exception caught at WcfErrorHandler{0} Method: {1}{2}Message:{3}",
                        Environment.NewLine, error.TargetSite.Name, Environment.NewLine, error.Message));

        var msgFault = newEx.CreateMessageFault();
        fault = Message.CreateMessage(version, msgFault, newEx.Action);
    }

}

app.config 的扩展

public class ExceptionLogBehaviorExtensionElement : BehaviorExtensionElement
{
    public override Type BehaviorType
    {
        get 
        {
            return typeof(EndpointBehavior);
        }
    }

    protected override object CreateBehavior()
    {
        return new EndpointBehavior();
    }
}

您的代码不起作用,因为IErrorHandler是一个仅限服务器端的功能。

在您的代码中,看起来您正在向客户端请求添加错误处理程序,但实际上并非如此。 这是因为clientRuntime.CallbackDispatchRuntime是一个类似服务器的实体,它存在于客户端中,用于在双工操作中接收来自真实服务器的消息。

关于您关于客户端异常处理的主要问题,我可以推荐的最好的是IClientMessageInspector 这里有一些代码可以帮助您入门:

public sealed class LoggingEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new LoggingInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

    public void Validate(ServiceEndpoint endpoint) { }
}

public sealed class LoggingInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        Console.WriteLine("BeforeSendRequest");
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        Console.WriteLine("AfterReceiveReply");
    }
}

但是,请注意IClientMessageInspector有一个缺点。 它的AfterReceiveReply方法在来自服务器的成功和错误回复时调用,但在根本没有任何回复时不调用,例如TimeoutExceptionEndpointNotFoundException等。

暂无
暂无

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

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