在现有 WCF SOAP 服务中添加 Http 标头不起作用
Posted
技术标签:
【中文标题】在现有 WCF SOAP 服务中添加 Http 标头不起作用【英文标题】:Adding Http Header in an existing WCF SOAP Service is not working 【发布时间】:2018-07-08 19:28:42 【问题描述】:我想为我的 WCF SOAP 服务添加一个 HTTP 标头。我的最终目标是通过这个 HTTP 标头发送 API 密钥。
下面是我的代码:
[ServiceBehavior(Namespace = "http://****.com/**/1.1")]
public class MyWcfSvc : IMyVerify
const int MaxResponseSize = 0xffff; // 64K max size - Normally it will be MUCH smaller than this
private static readonly NLogLogger Logger;
static MyWcfSvc()
Logger = new NLogLogger();
// Add an HTTP Header to an outgoing request
HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
requestMessage.Headers["User-Auth"] = "MyHttpHeaderValue";
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
我在 HTTP 请求标头下看不到 User-Auth
标头。
我也尝试了另一种方法。
public AnalyzeResponse Analyze(AnalyzeRequest analyzeRequest)
HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
requestMessage.Headers["User-Auth"] = "MyHttpHeaderValue";
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
.
.
. Rest of the service implementation
.
.
.
但是,我仍然没有在请求消息中看到任何 HTTP 标头信息。我正在使用 SOAP UI 发送请求并查看响应。
我应该怎么做?我是否应该对与课程相关的服务进行更改?或者我需要对web.config
文件进行一些更改?
【问题讨论】:
How to add a custom HTTP header to every WCF call? 我跟着那个,但它不起作用,这就是我问这个问题的原因。 不确定你想要完成什么......当你的服务发送它时在响应中输出一个HTTP头,或者当有人调用服务时,你想要传递和HTTP头,或者什么还有吗? 我建议您包括:服务器代码、客户端/消费代码、预期结果和实际结果(可能使用日志)...您的问题目前令人困惑。 【参考方案1】:SOAP 标头
要添加 SOAP 标头,请使用以下代码客户端:
using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
MessageHeader<string> header = new MessageHeader<string>("MyHttpHeaderValue");
var untyped = header.GetUntypedHeader("User-Auth", ns);
OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
// now make the WCF call within this using block
然后,服务器端,使用:
MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
string identity = headers.GetHeader<string>("User-Auth", ns);
注意。 ns
是标头 XML 元素的命名空间 URI。
HTTP 标头
添加 Http 标头:
// Add a HTTP Header to an outgoing request
HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
requestMessage.Headers["MyHttpHeader"] = "MyHttpHeaderValue";
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;
并抓住它服务器端
IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
WebHeaderCollection headers = request.Headers;
Console.WriteLine(request.Method + " " + request.UriTemplateMatch.RequestUri.AbsolutePath);
foreach (string headerName in headers.AllKeys)
Console.WriteLine(headerName + ": " + headers[headerName]);
【讨论】:
这是 SOAPHeader,不是 HttpHeader。 为答案竖起大拇指。我使用第二种方法使用 .Net 核心 API 将标头添加到 WCF 方法。谢谢。【参考方案2】:如果您尝试将 HTTP 请求标头添加到客户端请求,您可以按照以下步骤操作。
创建一个客户端消息检查器。例如:
public class CustomInspector : IClientMessageInspector
public void AfterReceiveReply(ref Message reply, object correlationState)
public object BeforeSendRequest(ref Message request, IClientChannel channel)
HttpRequestMessageProperty reqProps = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
if(reqProps == null)
reqProps = new HttpRequestMessageProperty();
reqProps.Headers.Add("Custom-Header", "abcd");
request.Properties[HttpRequestMessageProperty.Name] = reqProps;
return null;
创建一个端点行为来加载这个检查器:
public class CustomBehavior : IEndpointBehavior
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
clientRuntime.ClientMessageInspectors.Add(new CustomInspector());
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
public void Validate(ServiceEndpoint endpoint)
最后将此行为添加到端点。
class Program
static void Main(string[] args)
ChannelFactory<ICalculator> factory = new ChannelFactory<ICalculator>("BasicHttpsBinding_ICalculator");
factory.Endpoint.EndpointBehaviors.Add(new CustomBehavior());
var client = factory.CreateChannel();
var number = client.Add(1, 2);
Console.WriteLine(number.ToString());
上面的例子对我有用。我可以看到 Fiddler 的请求标头。
【讨论】:
【参考方案3】:在客户端有比 Leonardo 更好的解决方案。他的解决方案需要手动修改每个请求。 Here 是 ClientMessageInspector 的解决方案,它会自动为每个传出请求添加标头。
1:使用覆盖定义 MessageInspector: Bellow 是唯一一种覆盖方法,其余为空。
public class ClientMessageInspector : IClientMessageInspector
public object BeforeSendRequest(ref Message request, IClientChannel channel)
HttpRequestMessageProperty property = new HttpRequestMessageProperty();
property.Headers["User-Agent"] = "value";
request.Properties.Add(HttpRequestMessageProperty.Name, property);
return null;
...
-
将此消息检查器绑定到 EndPointBehavior。
Bellow 是唯一一种覆盖方法,其余为空。
public class CustomEndpointBehavior : IEndpointBehavior
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
...
-
最后一步是将新行为添加到 WCF 端点:
Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior());
【讨论】:
以上是关于在现有 WCF SOAP 服务中添加 Http 标头不起作用的主要内容,如果未能解决你的问题,请参考以下文章