我使用basicHttpBinding
通过HTTP调用IIS中托管的WCF服务。为了在服务器上传递验证,必须传递自定义标头值,从HTTP请求本身(标头和主体,如果存在)计算。
我可以使用代理(System.ServiceModel.Dispatcher.IClientMessageInspector
)上的客户端消息检查器(System.ServiceModel.Description.IEndpointBehavior
)自定义端点行为从呼叫中获取大部分信息,然后访问httpRequest
的标头消息对象。
但是,获取序列化为通过线路发送的消息内容似乎不会立即或明显可用。然而,我可以将消息本身存储在XmlSerializer中,该消息不会使其以与通过网络发送的格式相同的格式提供。
有没有办法获取此值?也许可以注入另一个检查员或行为,以便在打开或访问通道绑定时调用它?
答案 0 :(得分:3)
您必须实施自定义IDispatchMessageInspector
,并将其注入IOperationBehavior
或IEndpointBehavior
属性。 (在ApplyDispatchBehavior()
方法中)
在AfterReceiveRequest()
的{{1}}方法中,您只能通过复制它来获取邮件正文(一旦访问它就无效):
IDispatchMessageInspector
但是如果你只是想找到一个标题值,你可以简单地得到它:
private String GetRequestBody(ref Message message)
{
MessageBuffer buffer = message.CreateBufferedCopy(Int32.MaxValue);
message = buffer.CreateMessage();
String xml = null;
try
{
var copy = buffer.CreateMessage();
var dicReader = copy.GetReaderAtBodyContents();
xml = dicReader.ReadOuterXml();
}
catch (Exception e)
{
}
return xml;
}
创建一个像这样的属性,并将其放在要在WCF服务中跟踪的方法上:
private String TryGetHeader(Message request, String headerName)
{
if (request.Headers.FindHeader(headerName, "HeaderMessageNamespace") != -1)
return request.Headers.GetHeader<String>(headerName, "HeaderMessageNamespace");
return null;
}
并实现这样的检查器:
public class MyOperationBehaviorAttribute : Attribute, IOperationBehavior
{
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
if (dispatchOperation.Parent.MessageInspectors.OfType<MyMessageInspector>().Any() == false)
dispatchOperation.Parent.MessageInspectors.Add(new MyMessageInspector());
}
[...]
}
AND为客户端:
您必须在服务实例化之后注入行为。使用ClientBase类型的MyServiceClient和IEndpointBehavior myBehavior:
public class MyMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
var result = TryGetHeader(request, "name");
return null;
}
[...]
}
与
((ClientBase<ISomething>)service).Endpoint.Behaviors.Add(myBehavior);