您需要通过添加消息检查器来扩展 WCF 管道。客户端的消息检查器将负责添加标头,服务器的消息检查器将负责验证标头是否存在。
良好做法:如果要创建自定义标头,请指定自定义命名空间以简化查找。
public static class WCFSOAPNamespaces
{
private const string root = "http://www.schemas.productname.com/";
public const string Headers = root + "headers/";
}
服务器
IDispatchMessageInspector
处理所有传入服务器的消息。这是您将检查服务器上是否存在标头的地方。
public class DispatchMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
const string headerName = "nameOfTheHeader";
var someHeaderData = request.Headers.GetHeader<string>(headerName, WCFSOAPNamespaces.Headers);
//someHeaderData is the content that you want to check for every request. Attention: it throws System.ServiceModel.MessageHeaderException if the header doesn't exist
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState) { }
}
客户
IClientMessageInspector
处理客户端上的消息。如果您需要在消息中添加自定义标头,请点击此处。如果您不需要添加自定义标头,您可以跳过这第一段代码。
public class ClientMessageInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState) { }
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
const string headerName = "nameOfTheHeader";
string headerContent = ""; //fill this variable with the content
var header = new MessageHeader<string>(headerContent ?? string.Empty);
var untyped = header.GetUntypedHeader(headerName, WCFSOAPNamespaces.Headers);
request.Headers.Add(untyped);
return null;
}
}
两者(客户端和服务器)
即使您不需要客户端上的消息检查器,您仍然需要此配置才能将消息检查添加到服务器端应用程序。更具体地说,我们需要一个EndpointBehavior
来处理 MessageInspector。然后,我们需要设置服务端点以使用此自定义端点行为。
在此示例中,我将 2 个检查器置于相同的行为中,但如果需要,您可以创建单独的行为。
public class EndpointBehavior : BehaviorExtensionElement, IEndpointBehavior
{
public EndpointBehavior() { }
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)
{
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new DispatchMessageInspector());
}
public void Validate(ServiceEndpoint endpoint) { }
public override Type BehaviorType
{
get { return this.GetType(); }
}
protected override object CreateBehavior()
{
return new EndpointBehavior();
}
}
然后,将您的端点设置为使用此行为。
以编程方式
...
ServiceEndpoint endpoint;
...
endpoint.Behaviors.Add(new EndpointBehavior());
配置
...
<services>
<service name="...">
<endpoint address="..." binding="..." contract="..." behaviorConfiguration="endpointBehaviorName" />
</service>
...
<behaviors>
...
<endpointBehaviors>
<behavior name="endpointBehaviorName">
<customEndpointBehavior />
</behavior>
</endpointBehaviors>
</behaviors>
...
<extensions>
<behaviorExtensions>
<add name="customEndpointBehavior" type="FullNamespace.EndpointBehavior , AssemblyName" />
</behaviorExtensions>
</extensions>
从现在开始,所有的请求都会经过这个点。希望能帮助到你。