如何在WCF SOAP HTTPS/SSL握手过程中添加User-Agent请求头?
首先得澄清一个关键点:TLS/SSL握手本身是传输层的操作,不存在HTTP请求头的概念,User-Agent是HTTP协议的请求头,所以你实际要实现的应该是让WCF客户端发送的所有承载SOAP消息的HTTP请求都自动带上User-Agent头,而不用每次调用都手动写OperationContextScope的代码。下面给你两种靠谱的实现方案:
方案1:自定义消息检查器(代码级实现)
通过实现IClientMessageInspector接口,我们可以在每次请求发送前自动注入User-Agent头,一劳永逸解决重复代码的问题。
步骤1:实现消息检查器
public class UserAgentMessageInspector : IClientMessageInspector { private readonly string _userAgentValue; public UserAgentMessageInspector(string userAgent) { _userAgentValue = userAgent; } // 请求发送前触发,添加HTTP头 public object BeforeSendRequest(ref Message request, IClientChannel channel) { var httpRequestProp = request.Properties["httpRequest"] as HttpRequestMessageProperty; // 如果HTTP请求属性不存在,先创建 if (httpRequestProp == null) { httpRequestProp = new HttpRequestMessageProperty(); request.Properties.Add("httpRequest", httpRequestProp); } // 设置User-Agent头 httpRequestProp.Headers["User-Agent"] = _userAgentValue; return null; } // 回复接收后触发,这里不需要处理,留空即可 public void AfterReceiveReply(ref Message reply, object correlationState) { } }
步骤2:创建Endpoint行为扩展
需要把上面的检查器绑定到客户端的Endpoint行为上:
public class UserAgentEndpointBehavior : IEndpointBehavior { private readonly string _userAgent; public UserAgentEndpointBehavior(string userAgent) { _userAgent = userAgent; } public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } // 将检查器添加到客户端运行时 public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.ClientMessageInspectors.Add(new UserAgentMessageInspector(_userAgent)); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } }
步骤3:绑定到WCF客户端
创建客户端实例时,把这个行为添加上就行:
var yourWcfClient = new YourServiceClient(); // 添加自定义行为,传入你的User-Agent值 yourWcfClient.Endpoint.Behaviors.Add(new UserAgentEndpointBehavior("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11")); // 之后正常调用服务方法,每次请求都会自动带上User-Agent头 yourWcfClient.YourServiceMethod();
方案2:配置文件方式(适用于.NET Framework)
如果不想写硬编码,也可以通过配置文件来实现,适合需要灵活修改User-Agent的场景。
步骤1:定义配置扩展元素
public class UserAgentBehaviorExtensionElement : BehaviorExtensionElement { [ConfigurationProperty("userAgent", IsRequired = true)] public string UserAgent { get => (string)this["userAgent"]; set => this["userAgent"] = value; } public override Type BehaviorType => typeof(UserAgentEndpointBehavior); protected override object CreateBehavior() { return new UserAgentEndpointBehavior(UserAgent); } }
步骤2:修改App.config/Web.config
注册扩展并绑定到客户端Endpoint:
<system.serviceModel> <!-- 注册自定义行为扩展 --> <extensions> <behaviorExtensions> <add name="userAgent" type="你的命名空间.UserAgentBehaviorExtensionElement, 你的程序集名称" /> </behaviorExtensions> </extensions> <!-- 定义带User-Agent的Endpoint行为 --> <behaviors> <endpointBehaviors> <behavior name="UserAgentEnabledBehavior"> <userAgent userAgent="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11" /> </behavior> </endpointBehaviors> </behaviors> <!-- 客户端配置,引用上面的行为 --> <client> <endpoint address="https://你的服务地址" binding="basicHttpBinding" bindingConfiguration="HttpsBinding" contract="你的服务契约接口" behaviorConfiguration="UserAgentEnabledBehavior" /> </client> <!-- HTTPS绑定配置 --> <bindings> <basicHttpBinding> <binding name="HttpsBinding"> <security mode="Transport"> <transport clientCredentialType="None" /> </security> </binding> </basicHttpBinding> </bindings> </system.serviceModel>
额外说明
你之前用OperationContextScope添加的是SOAP消息头,而不是HTTP请求头。如果服务端要求的是HTTP层面的User-Agent,上面的方案更合适——它们直接操作底层HTTP请求的头信息,确保所有请求都自动携带。
内容的提问来源于stack exchange,提问作者Mike Bestvina
相关产品推荐
相关产品推荐

