您的位置:首页 > 其它

跟着Artech学习WCF扩展(4) 扩展MessageInspector

2011-10-07 21:11 513 查看
自定义MessageInspector

在client端和service端都有自己的MessageInspector,client端叫做ClientMessageInspector,实现System.ServiceModel.Dispatcher.IClientMessageInspector interface,而service端叫做 DispatchMessageInspector, 实现了System.ServiceModel.Dispatcher.IDispatchMessageInspector interface。DispatchMessageInspector允许你在request message交付到具体的DispatchOperation付诸执行之前或者reply message返回client之前对incoming message/outgoing message进行检验、修改或者其他一些基于message的操作;

IDispatchMessageInspector的定义很简单

public interface IDispatchMessageInspector
{
// Methods
object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext);
void BeforeSendReply(ref Message reply, object correlationState);
}


在实际的项目开发中,MessageInspector使用相当广范,比如:我们可以定义自己的MessageInspector实现Logging功能;或者在Client端通过ClientMessageInspector添加一些与业务无关的context信息,并在service通过DispatchMessageInspector将其取出。在本系列后续的部分我将给你一个application context propagation的具体应用。

剩下的地方在这里:点我

代码下载:点我

Client端对 IClientMessageInspector 进行实现

在service端对IDispatchMessageInspector进行实现

但Artech在service端对 ICallContextInitializer进行了实现

出去学习的目的,拼拼代码 也把IDispatchMessageInspector实现了

不过不知道对不对

  自己拼代码实在是盲人摸像 搞了一天才弄明白,不对是还没弄明白

通过细查 发现这个扩展 实在是太有用了


部分代码如下作为备份

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Artech.ContextPropagation
{
public class DispatchMessageInspectorTest:System.ServiceModel.Dispatcher.IDispatchMessageInspector
{
public bool IsBidirectional
{ get; set; }

public DispatchMessageInspectorTest()
: this(false)
{

}

public DispatchMessageInspectorTest(bool isBidirectional)
{
this.IsBidirectional = isBidirectional;
}

//DispatchMessageInspector
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
ApplicationContext context = request.Headers.GetHeader<ApplicationContext>(ApplicationContext.ContextHeaderLocalName, ApplicationContext.ContextHeaderNamespace);
if (context == null)
{
return null;
}

ApplicationContext.Current = context;
return ApplicationContext.Current;
}

public void BeforeSendReply(ref Message reply, object correlationState)
{

if (!this.IsBidirectional)
{
return;
}

ApplicationContext context = correlationState as ApplicationContext;
if (context == null)
{
return;
}
MessageHeader<ApplicationContext> contextHeader = new MessageHeader<ApplicationContext>(context);
OperationContext.Current.OutgoingMessageHeaders.Add(contextHeader.GetUntypedHeader(ApplicationContext.ContextHeaderLocalName, ApplicationContext.ContextHeaderNamespace));
ApplicationContext.Current = null;

}

}
}


 

=========

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Artech.ContextPropagation
{
public class DispatchMessageInspectorTestBehavior : IEndpointBehavior
{
public bool IsBidirectional
{ get; set; }

public DispatchMessageInspectorTestBehavior()
: this(false)
{

}

public DispatchMessageInspectorTestBehavior(bool isBidirectional)
{
this.IsBidirectional = isBidirectional;
}

public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{

}

public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new ContextAttachingMessageInspector(this.IsBidirectional));

}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{

DispatchMessageInspectorTest inspector = new DispatchMessageInspectorTest(this.IsBidirectional);
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
}

public void Validate(ServiceEndpoint endpoint)
{

}
}
}


 

==============

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Configuration;
using System.Configuration;

namespace Artech.ContextPropagation
{
public class DispatchMessageInspectorTestElement:BehaviorExtensionElement
{
[ConfigurationProperty("isBidirectional", DefaultValue = false)]
public bool IsBidirectional
{
get
{
return (bool)this["isBidirectional"];
}
set
{
this["isBidirectional"] = value;
}
}

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

protected override object CreateBehavior()
{
return new DispatchMessageInspectorTestBehavior(IsBidirectional);
}
}
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: