我有一个托管在Windows服务中的WCF服务.使用此服务的客户端每次调用服务方法时都必须传递一个标识符(因为该标识符对于被调用的方法应该做什么很重要).我认为以某种方式将此标识符放入WCF头信息是个好主意.
如果是个好主意,我该如何自动将标识符添加到标题信息中.换句话说,每当用户调用WCF方法时,标识符必须自动添加到标头中.
更新: 使用WCF服务的客户端是Windows应用程序和Windows Mobile应用程序(使用Compact Framework).
这样做的好处是它适用于每次通话.
创建一个实现IClientMessageInspector的类.在BeforeSendRequest方法中,将自定义标头添加到外发邮件中.它可能看起来像这样:
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) { HttpRequestMessageProperty httpRequestMessage; object httpRequestMessageObject; if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject)) { httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty; if (string.IsNullOrEmpty(httpRequestMessage.Headers[USER_AGENT_HTTP_HEADER])) { httpRequestMessage.Headers[USER_AGENT_HTTP_HEADER] = this.m_userAgent; } } else { httpRequestMessage = new HttpRequestMessageProperty(); httpRequestMessage.Headers.Add(USER_AGENT_HTTP_HEADER, this.m_userAgent); request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage); } return null; }
然后创建一个端点行为,将消息检查器应用于客户端运行时.您可以通过属性或使用行为扩展元素的配置来应用行为.
以下是如何将HTTP用户代理标头添加到所有请求消息的一个很好的示例.我在一些客户中使用它.您也可以通过实现IDispatchMessageInspector在服务端执行相同的操作.
这是你的想法吗?
更新: 我发现了紧凑框架支持的WCF功能列表.我相信消息检查员被归类为"渠道可扩展性",根据这篇文章,它受到紧凑框架的支持.
您可以使用以下命令将其添加到呼叫
using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel)) { MessageHeaderheader = new MessageHeader ("secret message"); var untyped = header.GetUntypedHeader("Identity", "http://www.my-website.com"); OperationContext.Current.OutgoingMessageHeaders.Add(untyped); // now make the WCF call within this using block }
然后,服务器端你使用以下方法获取它:
MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders; string identity = headers.GetHeader("Identity", "http://www.my-website.com");
如果您只想为服务的所有请求添加相同的标头,您可以不使用任何编码!
只需在客户端配置文件的端点节点下添加头节点和必需的头
Value
这是另一个有用的解决方案,使用ChannelFactory
作为代理手动将自定义HTTP标头添加到客户端WCF请求.这必须针对每个请求进行,但如果您只是需要对代理进行单元测试以准备非.NET平台,那么就足够了.
// create channel factory / proxy ... using (OperationContextScope scope = new OperationContextScope(proxy)) { OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = new HttpRequestMessageProperty() { Headers = { { "MyCustomHeader", Environment.UserName }, { HttpRequestHeader.UserAgent, "My Custom Agent"} } }; // perform proxy operations... }
这类似于NimsDotNet的答案,但显示了如何以编程方式执行此操作.
只需将标题添加到绑定即可
var cl = new MyServiceClient(); var eab = new EndpointAddressBuilder(cl.Endpoint.Address); eab.Headers.Add( AddressHeader.CreateAddressHeader("ClientIdentification", // Header Name string.Empty, // Namespace "JabberwockyClient")); // Header Value cl.Endpoint.Address = eab.ToEndpointAddress();
var endpoint = new EndpointAddress(new Uri(RemoteAddress), new[] { AddressHeader.CreateAddressHeader( "APIKey", "", "bda11d91-7ade-4da1-855d-24adfe39d174") });