kappie
kappie

Reputation: 231

How to add HTTP Header to SOAP Client

Can someone answer me if it is possible to add HTTP header to soap client web-service calls. After surfing Internet the only thin I found was how to add SOAP header.

The code looks like this:

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

UPDATE:

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>

Header property in the envelop should be empty

Upvotes: 23

Views: 53821

Answers (5)

framerelay
framerelay

Reputation: 676

To add HTTP header to standard generated SOAP client (through either service reference or by generating client using svcutil) you can leverage Endpoint.Behaviors extension point which I found the most convenient.

Couple steps need to be accomplished. First we need to create message inspector with actual feature which will add HTTP header ("HEADER_WHICH_WE_WANT") to each SOAP request

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;
}}

next we need to add this MessageInspector to IEndpointBehavior interface implementation at clientRuntime.MessageInspectors point

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());
  }
}

and the last thing is to register this behavior for SOAP client

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

that's it, now each SOAP call will be equipped with custom HTTP header "HEADER_WHICH_WE_WANT" with value "Actual Value we want" we specified in our code.

Upvotes: 4

Carlos Toledo
Carlos Toledo

Reputation: 2684

Some of those answers would add headers to the XML body content of the request. To add the headers to the request itself follow:

SoapServiceClient client = new SoapServiceClient();

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

    var result = client.MyClientMethod();
}

Note the change of OperationContext for WebOperationContext. Is a helper class that provides easy access to contextual properties of Web requests and responses.

Upvotes: 0

Ivan Melnikov
Ivan Melnikov

Reputation: 771

Try to use this:

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();
}

See here for more detail.

Upvotes: 64

Qu&#233; Padre
Qu&#233; Padre

Reputation: 2083

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

Upvotes: 1

Farhan Ghumra
Farhan Ghumra

Reputation: 15296

Try this

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();
}

Upvotes: 3

Related Questions