wcf :自定义消息检查器未连接 [英] wcf :custom message inspector does not get wired up

查看:19
本文介绍了wcf :自定义消息检查器未连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在服务端做了一个自定义的错误处理程序:

I have made a custom error handler on the service side:

 public class GlobalErrorHandler : Attribute, IErrorHandler, IServiceBehavior
    {
        public void AddBindingParameters(
            ServiceDescription serviceDescription,
            ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints,
            BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            IErrorHandler errorHandler = new GlobalErrorHandler();

            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;

                if (channelDispatcher != null)
                {
                    channelDispatcher.ErrorHandlers.Add(errorHandler);

                }
            }
        }

        public bool HandleError(Exception error)
        {
            Trace.TraceError(error.ToString());

            if (error is FaultException)
                return false; // Let WCF do normal processing
            else
                return true; // Fault message is already generated
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            if (error is FaultException)
            {
                // Let WCF do normal processing
            }
            else
            {
                // Generate fault message manually
                MessageFault messageFault = MessageFault.CreateFault(
                    new FaultCode("Sender"), new FaultReason(error.Message),
                    error, new NetDataContractSerializer());
                fault = Message.CreateMessage(version, messageFault, null);
            }
        }

    }

    public class ErrorHandlerElement : BehaviorExtensionElement
    {
        protected override object CreateBehavior()
        {
            return new GlobalErrorHandler();
        }

        public override Type BehaviorType
        {
            get { return typeof (GlobalErrorHandler); }
        }
    }

我在客户端定义了一个自定义消息检查器:

I have defined a custom message inspector on the client side :

public class MessageInspector : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            if (reply.IsFault)
            {
                //do some processing
            }
        }

        public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel)
        {
            return null;
        }
}

我有一个连接消息检查器的自定义行为:

I have a custom behaviour which wire ups the message inspector :

public class NewtonsoftJsonBehavior : WebHttpBehavior
{
 public override void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime       clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new MessageInspector());
        }
}

并且此行为通过工厂以编程方式应用:

and this behaviour is applied programatically through a factory :

public class JsonWebServiceHostFactory : WebServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            var host =  base.CreateServiceHost(serviceType, baseAddresses);
            //return host;
            //ServiceEndpoint ep = host.AddServiceEndpoint(serviceType, new WebHttpBinding(), "");
            //host.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior { HelpEnabled = true });     
            //return host;

            WebHttpBinding webBinding = new WebHttpBinding();

            host.AddServiceEndpoint(serviceType, webBinding, "").Behaviors.Add(new NewtonsoftJsonBehavior());
            return host;
        }
    }

但是,当我调试并在服务中生成错误异常时,会调用 globalerrorhandler,但调试器从未进入消息检查器.知道为什么吗?

However when I debug and I generate a faultexception in the service, the globalerrorhandler gets called , but the debugger never steps into the message inspector. Any idea why?

推荐答案

要在 WCF 服务端创建消息检查器,请使用 IDispatchMessageInspector 的实现,而不是:IClientMessageInspector.

To create a Message Inspector on WCF service side, use an implementation of IDispatchMessageInspector instead of: IClientMessageInspector.

示例:

服务:

EndpointAddress endpoint = new EndpointAddress("http://localhost:9001/Message");

WebServiceHost svcWebHost = new WebServiceHost(typeof(Service.Message), endpoint.Uri);

CustomServiceBehavior serviceBehavior = new CustomServiceBehavior();
svcWebHost.Description.Behaviors.Add(serviceBehavior);

Binding webHttpBinding = new WebHttpBinding();

ServiceEndpoint serviceEndpoint = svcWebHost.AddServiceEndpoint(typeof(Service.IMessage), webHttpBinding, endpoint.Uri);

ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
svcWebHost.Description.Behaviors.Add(smb);

ServiceDebugBehavior sdb = svcWebHost.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.IncludeExceptionDetailInFaults = true;

svcWebHost.Open();

服务合同

[ServiceContract]
public interface IMessage
{
    [OperationContract]
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
    Model.TestResponse Test();
}

服务实施

public class Message : IMessage
{
    public Model.TestResponse Test()
    {
        return new Model.TestResponse() { success = true, message = "OK!" };
    }
}

CustomServiceBehavior 实现 IServiceBehavior:

public class CustomServiceBehavior : IServiceBehavior
{
    public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {
        CustomEndpointBehavior endpointBehavior = new CustomEndpointBehavior();
        foreach (var endpoint in serviceDescription.Endpoints)
            endpoint.EndpointBehaviors.Add(endpointBehavior);
    }

    public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {

    }
}

CustomEndpointBehavior 实现 IEndpointBehavior

public class CustomEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {

    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    {
        var inspector = new CustomDispatchMessageInspector();
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
    }

    public void Validate(ServiceEndpoint endpoint)
    {

    }
}

CustomDispatchMessageInspector 实现 IDispatchMessageInspector

public class CustomDispatchMessageInspector : IDispatchMessageInspector
{
    public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
    {
        return null;
    }

    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {
        var httpResponse = ((HttpResponseMessageProperty)reply.Properties["httpResponse"]);
        httpResponse.Headers.Add("user-agent", "My Browser");
    }
}

这个例子是一个没有配置文件的 WCF 自托管(在代码中配置 WCF 服务),它返回一个 Json 并在 HTTP 响应(用户代理:我的浏览器)中发送一个自定义标头.

This example is a WCF Self Hosted without configuration file (Configuring WCF Services in Code) that return a Json and send a custom header in HTTP Response (user-agent:My Browser).

要测试此代码:

  1. 创建一个 Windows 控制台应用程序
  2. 插入代码(每个阻塞在一个类中)
  3. 运行应用程序
  4. 使用浏览器打开网址:http://localhost:9001/Message/Test
  5. 响应是一个 Json:{"message":"OK!","success":true}
  6. 您可以检查响应并查看自定义标题:user-agent:My Browser"

这篇关于wcf :自定义消息检查器未连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆