我正在使用具有多个操作的WCF服务,此服务要求我在调用任何操作时添加传出消息属性。
目前我只是在代码中调用服务时添加属性。
以下是我的代码:
using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties.Add("P1", "Test User");
OperationContext.Current.OutgoingMessageProperties.Add("P2", "Test Type");
response = client.process(request);
}
如何创建动态添加这些消息属性的WCF扩展?
我对扩展知之甚少,但还不足以拦截和添加这些标题。
答案 0 :(得分:2)
要自动为邮件添加一些标题,您必须实施 IClientMessageInspector 。它允许您为外发消息更改任何内容。
编辑2:
public class ClientMessageInspector : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
//following example is for adding http header.
//If you have another protocol you can add any other message
//manipulation code instead.
//HttpResponseMessageProperty.Name returns "httpResponse".
HttpResponseMessageProperty httpProp = null;
if (request.Properties.ContainsKey(HttpResponseMessageProperty.Name))
{
httpProp = (HttpResponseMessageProperty)request.Properties[HttpResponseMessageProperty.Name];
}
else
{
httpProp = new HttpResponseMessageProperty();
request.Properties.Add(HttpResponseMessageProperty.Name, httpProp);
}
httpProp.Headers.Add("YouHeader", "YourValue");
//as I mentioned you can change a message in a way you need
request.Properties.Add("P1", "Test User");
request.Headers.Add(MessageHeader.CreateHeader("P1", "htt p://site.com/", "Test User"));
return null;
}
public void AfterReceiveReply(ref Message reply, object correlationState) { }
}
public class ClientMessageInspectorBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(new ClientMessageInspector());
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
public class ClientMessageInspectorExtensionElement : BehaviorExtensionElement
{
protected override object CreateBehavior()
{
return new ClientMessageInspectorBehavior();
}
public override Type BehaviorType
{
get
{
return typeof(ClientMessageInspectorBehavior);
}
}
}
您的配置文件应如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint
address="http://localhost:8000/CoolerService"
behaviorConfiguration="coolerBehaviour"
binding="webHttpBinding"
contract="CoolerService.ICoolerService"
name="coolerEndpoint">
</endpoint>
</client>
<extensions>
<behaviorExtensions>
<add name="customHeaderAdder" type="Extensions.ClientMessageInspectorExtensionElement, Extensions" />
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="coolerBehaviour">
<customHeaderAdder />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
答案 1 :(得分:0)
实现IClientMessageInspector,就像前面的回答所说的那样,但是如果你想添加HTTP头,请使用类似的代码块,就像你使用过的那样 - 在BeforeSendRequest中。
using (new OperationContextScope((IContextChannel)channel))
{
OperationContext.Current.OutgoingMessageProperties.Add("P1", "Test User");
OperationContext.Current.OutgoingMessageProperties.Add("P2", "Test Type");
response = client.process(request);
}
答案 2 :(得分:0)
在我看来,您只需设置OperationContext.Current
而无需像这样创建OperationScope
:
OperationContext.Current = new OperationContext(client.InnerChannel);
OperationContext.Current.OutgoingMessageProperties.Add("P1", "Test User");
这可能看起来像是一种不好的做法,但是如果你看一下documentation,你会发现OperationContext.Current
属性是
实际上限定为当前线程(使用ThreadStatic属性),因此线程安全。
请注意,同一线程中的client
的其他实例不会添加消息属性,因为OperationContext
绑定到客户端通道。