如何为SOAP客户端添加HTTP头

20

请问是否可以在调用SOAP客户端Web服务时添加HTTP头。在浏览互联网后,我发现唯一的东西是如何添加SOAP头。

代码如下:

var client =new MyServiceSoapClient();
//client.AddHttpHeader("myCustomHeader","myValue");//There's no such method, it's just for clearness
var res = await client.MyMethod();

更新:

The request should look like this
POST https://service.com/Service.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.host.com/schemas/Authentication.xsd/Action"
Content-Length: 351
MyHeader: "myValue"
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header/>
  <s:Body>
    <myBody>BodyGoesHere</myBody>
  </s:Body>
</s:Envelope>

信封中的头部属性应该为空。

5个回答

60

试着使用这个:

SoapServiceClient client = new SoapServiceClient();

using(new OperationContextScope(client.InnerChannel)) 
{
    // // Add a SOAP Header (Header property in the envelope) to an outgoing request. 
    // MessageHeader aMessageHeader = MessageHeader
    //    .CreateHeader("MySOAPHeader", "http://tempuri.org", "MySOAPHeaderValue");
    // OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader);

    // Add a HTTP Header to an outgoing request
    HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();
    requestMessage.Headers["MyHttpHeader"] = "MyHttpHeaderValue";
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] 
       = requestMessage;

    var result = client.MyClientMethod();
}

更多细节请查看这里


2
这应该被标记为答案,对我有用。谢谢。 - Syed Waqas
3
如果当前客户端中不存在 InnerChanner(我正在尝试使用 SOAP 调用),该怎么办? - NewPHPer
什么是 SoapServiceClient - tRuEsAtM
在我的情况下,InnerChannel不存在,因为我使用了WSDL.exe来创建客户端代理,而不是svcutil.exe。 - Peter PitLock
运行得非常好,帮我省了不少麻烦。还有,感谢你留下了注释代码,这正是我想要的——将标头添加到信封内部。 - OrionMD
我得到的错误信息是:“所提供的URI方案'https'无效;期望'http'。(参数'via')”。如果我将URL更改为http,则似乎可以正常工作,但在我的情况下这不是有效的URL。 - Antonio Rodríguez

3
要将HTTP标头添加到通过服务引用或使用svcutil生成的标准生成的SOAP客户端中,您可以利用Endpoint.Behaviors扩展点,我发现这是最方便的方法。
需要完成几个步骤。首先,我们需要创建消息检查器,并添加实际功能,该功能将在每个SOAP请求中添加HTTP标头(“HEADER_WHICH_WE_WANT”)。
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

class MessageInspector : IClientMessageInspector
{
  public object BeforeSendRequest(ref Message request, IClientChannel channel)
  {
    var property = request.Properties.ContainsKey(HttpRequestMessageProperty.Name)?
    request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty: new HttpRequestMessageProperty();

    if (null == property)
      return null;

    property.Headers["HEADER_WHICH_WE_WANT"] = "Actual Value we want";
    request.Properties[HttpRequestMessageProperty.Name] = property;
    return null;
}}

接下来,我们需要将该MessageInspector添加到IEndpointBehavior接口实现中的clientRuntime.MessageInspectors点。
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

internal class InspectorBehavior : IEndpointBehavior
{
  public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  {
   clientRuntime.MessageInspectors.Add(new MessageInspector());
  }
}

最后一件事是为SOAP客户端注册此行为。

SoapClient.Endpoint.Behaviors.Add(new InspectorBehavior());

好的,现在每个SOAP调用都将配备我们在代码中指定的值为“Actual Value we want”的自定义HTTP头“HEADER_WHICH_WE_WANT”。


对我来说,这是更好的答案,因为您只需要执行一次,而且对于所有后续调用都有效,无论从哪里调用它+1。 - MeeKaaH
对我来说,这是更好的答案,因为你只需要做一次,而且对于所有后续的调用都有效,不论从哪里调用,+1。 - undefined

3

试试这个

var client = new MyServiceSoapClient();
using (var scope = new OperationContextScope(client.InnerChannel))
{
    // Create a custom soap header
    var msgHeader = MessageHeader.CreateHeader("myCustomHeader", "The_namespace_URI_of_the_header_XML_element", "myValue");
    // Add the header into request message
    OperationContext.Current.OutgoingMessageHeaders.Add(msgHeader);

    var res = await client.MyMethod();
}

谢谢,这不是我需要的。我已经更新了描述,请看一下。 - kappie
这看起来不错,但它进行了编码。例如,< 变成了 &lt;。有什么想法可以防止这种情况发生吗?我已经检查了所有的重载,但没有一个似乎能够原样添加头文件,即RAW。 - Mike de Klerk

1
var client = new MyServiceSoapClient();
using (new OperationContextScope(InnerChannel))
{ 
    WebOperationContext.Current.OutgoingRequest.Headers.Add("myCustomHeader", "myValue");                
}

谢谢,这不是我需要的。我已经更新了描述,请看一下。 - kappie
MyServiceSoapClient是什么? - tRuEsAtM
如果你正在尝试在RequestHeader中传递Customer Header,那么这将是正确的答案。对我来说,这就是答案。 - Sandeep Maharjan

0

其中一些答案会向请求的 XML 正文内容添加标头。 要将标头添加到请求本身,请按照以下步骤进行:

SoapServiceClient client = new SoapServiceClient();

using(var scope = new OperationContextScope(client.InnerChannel)) 
{
     WebOperationContext.Current.OutgoingRequest.Headers.
           Add("headerKey", "headerValue");

    var result = client.MyClientMethod();
}

请注意将OperationContext更改为WebOperationContext。它是一个帮助类,提供了对Web请求和响应的上下文属性的简单访问。

这只是一个.NET 4的解决方案。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接