使用代码而不是配置文件将消息检查器添加到 WCF 服务

Posted

技术标签:

【中文标题】使用代码而不是配置文件将消息检查器添加到 WCF 服务【英文标题】:Add Message Inspector to WCF service in code rather that config file 【发布时间】:2015-10-14 10:56:35 【问题描述】:

我正在研究 Microsoft 培训工具包 (WCF) 中的一个示例。它需要将消息检查添加到服务中。

到目前为止,我已经创建了检查实现类、消息行为类和消息行为类扩展。

我不想通过配置文件添加行为,而是将其添加到服务主机文件中。下面是实现类...

 public class MessageTrace : IDispatchMessageInspector
    
        private Message TraceMessage(MessageBuffer buffer)
        
            Message msg = buffer.CreateMessage();
            StringBuilder sb = new StringBuilder("Message content");
            sb.Append(msg.ToString());
            Console.WriteLine(sb.ToString());
            return buffer.CreateMessage();
        

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        
            request = TraceMessage(request.CreateBufferedCopy(Int32.MaxValue));
            return null;
        

        public void BeforeSendReply(ref Message reply, object correlationState)
        
            reply = TraceMessage(reply.CreateBufferedCopy(Int32.MaxValue));
        
    

public class TraceMessageBehavior : IEndpointBehavior
    
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        
            MessageTrace inspector = new MessageTrace();
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        

        public void Validate(ServiceEndpoint endpoint)
        
    

 public class TraceMessageBehaviorExtension : BehaviorExtensionElement
    
        public override Type BehaviorType
        
            get  return typeof(TraceMessageBehavior); 
        

        protected override object CreateBehavior()
        
            return new TraceMessageBehavior();
        
    

【问题讨论】:

【参考方案1】:

您只能通过以下方式使用代码来实现。

    首先在您的服务类上使用属性。创建一个从 IServiceBehavior 继承的新属性。

    [AttributeUsage(AttributeTargets.Class)]
    public class TraceServiceBehavior : Attribute, IServiceBehavior
    
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    
    
    
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    
        foreach (ChannelDispatcher cDispatcher in serviceHostBase.ChannelDispatchers)
        
            foreach (EndpointDispatcher eDispatcher in cDispatcher.Endpoints)
            
                eDispatcher.DispatchRuntime.MessageInspectors.Add(new MessageTrace());
            
        
    
    
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    
    
    
    

然后用这个属性装饰你的服务类

[TraceServiceBehavior]
public class Service1 : IService1

     // Methods

    创建从 IServiceBehavior 扩展而来的 ServiceBehavior,代码同上,只删除属性。

    公共类 TraceServiceBehavior : IServiceBehavior

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    
    
    
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    
        foreach (ChannelDispatcher cDispatcher in serviceHostBase.ChannelDispatchers)
        
            foreach (EndpointDispatcher eDispatcher in cDispatcher.Endpoints)
            
                eDispatcher.DispatchRuntime.MessageInspectors.Add(new MessageTrace());
            
        
    
    
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    
    
    
    

然后在 ServiceHost 中,以编程方式添加行为。

ServiceHost host = new ServiceHost(typeof(WcfService1.Service1));
host.Description.Behaviors.Add(new WcfService1.TraceServiceBehavior());

【讨论】:

属性好像不用加了【参考方案2】:

我可以简单地使用以下命令添加端点行为:

ServiceEndpoint endpoint;
endpoint = host.AddServiceEndpoint(typeof(ISimpleService), httpBinding, "");
endpoint.EndpointBehaviors.Add(new TraceMessageBehavior());

所以我在应用配置中定义了扩展和端点行为,但是端点是在源文件中定义的。因此,我也想在源文件中添加 endpointBehavior。

【讨论】:

以上是关于使用代码而不是配置文件将消息检查器添加到 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

WCF ChannelFactory 和通道 - 缓存、重用、关闭和恢复

强制 Soap/WCF 使用 HTTP 而不是 TCP 协议

WCF 最大消息大小配额

WCF - 检查正在发送/接收的消息?

使用 WCF-Custom 处理 tableop 选择查询返回原始消息.. 不是数据

WCF 自定义行为的依赖注入