原文:https://www.cnblogs.com/yanglang/p/7063743.html
我们需要拦截消息,并把消息打印出来,那么我们就需要一个拦截器,叫做MessageInspector,WCF为我们提供了两种拦截器:
客户端拦截器 IClientMessageInspector
提供两个接口
BeforeSendRequest:向服务器发送请求前执行
AfterReceiveReply:接收到服务器的回复消息后执行
服务端拦截器 IDispatchMessageInspector
他也提供两个接口
AfterReceiveRequest:invoke操作之前执行
BeforeSendReply:发送reply给客户端之前执行
在这里我们在服务端设置个拦截器,然后打印出请求和回复的消息,所以我们使用IDispatchMessageInspector这个接口
实现接口 MessageInspector.cs
1 namespace Cookiezhi.WcfStudy.Hosting.MessageInspect 2 { 3 public class MessageInspector : IDispatchMessageInspector 4 { 5 public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 6 { 7 Console.WriteLine(request.ToString()); 8 return DateTime.Now; 9 } 10 11 public void BeforeSendReply(ref Message reply, object correlationState) 12 { 13 Console.WriteLine(reply.ToString()); 14 DateTime requestTime = (DateTime)correlationState; 15 16 var duration = DateTime.Now - requestTime; 17 Console.WriteLine(duration); 18 } 19 } 20 }
其中AfterReceiveRequest先执行,然后去执行远程方法,然后再执行BeforeSendReply,所以在这里加了一个操作计时的功能(可选)。
然后我们要将这个拦截器给寄宿在我们的终结点上,所以需要定义一个终结点行为(EndpointBehavior),并寄宿在服务上。
MessageInspectorBehavior.cs,在ApplyDispatchBehavior方法实现中将我们新建的Inspector实例加到dispatcher的MessageInspectors中
1 namespace Cookiezhi.WcfStudy.Hosting.MessageInspect 2 { 3 public class MessageInspectorBehavior : IEndpointBehavior 4 { 5 public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 6 { 7 } 8 9 public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 10 { 11 } 12 13 public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 14 { 15 endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MessageInspector());
16 } 17 18 public void Validate(ServiceEndpoint endpoint) 19 { 20 } 21 } 22 }
最后创建一个配置元素用于在配置文件中给终结点配置这个行为.
1 namespace Cookiezhi.WcfStudy.Hosting.MessageInspect 2 { 3 public class MessageInspectorExtensionElement : BehaviorExtensionElement 4 { 5 public override Type BehaviorType 6 { 7 get { return typeof(MessageInspectorBehavior); } 8 } 9 10 protected override object CreateBehavior() 11 { 12 return new MessageInspectorBehavior(); 13 } 14 } 15 }
下面就是配置这个行为了
App.config
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 4 <system.serviceModel> 5 <extensions> 6 <behaviorExtensions> 7 <add name="messageInspector" type="Cookiezhi.WcfStudy.Hosting.MessageInspect.MessageInspectorExtensionElement, Cookiezhi.WcfStudy.Hosting"/> 8 </behaviorExtensions> 9 </extensions> 10 11 <behaviors> 12 <serviceBehaviors> 13 <behavior name="mexBehavior"> 14 <serviceMetadata httpGetEnabled="true"/> 15 </behavior> 16 </serviceBehaviors> 17 <endpointBehaviors> 18 <behavior name="messageInspector"> 19 <messageInspector /> 20 </behavior> 21 </endpointBehaviors> 22 </behaviors> 23 24 <services> 25 <service name="Cookiezhi.WcfStudy.Services.ComplexCalculateService" behaviorConfiguration="mexBehavior"> 26 <endpoint address="" binding="basicHttpBinding" contract="Cookiezhi.WcfStudy.Contracts.ServiceContracts.IComplexCalculate" behaviorConfiguration="messageInspector" /> 27 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 28 <host> 29 <baseAddresses> 30 <add baseAddress="http://127.0.0.1:9999/complexcalcservice"/> 31 </baseAddresses> 32 </host> 33 </service> 34 </services> 35 36 </system.serviceModel> 37 38 <startup> 39 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 40 </startup> 41 </configuration>
客户端的代码不要做出任何的改变,
然后我们尝试一下
Great! 我们成功的拦截了请求,并将请求信息打印了出来。
总结,有了这个拦截器,我们可以做很多的事情,比如修改消息头和消息体,计算消息的大小(流量统计),统计服务调用的次数和平均时间,客户端情况,等等。