使用代码而不是配置文件将消息检查器添加到 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 协议