Adding Http Header in an existing WCF SOAP Service is not working

To add a SOAP header, use the following code client-side:

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
}

And then, server-side, grab it using:

MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
string identity = headers.GetHeader<string>("User-Auth", ns);

NB. ns is The namespace URI of the header XML element.

To add an Http header:

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

And to grab it server-side

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

If you are trying to add an HTTP request header to the client request, you can follow the procedure below.

Create a client message inspector. For example:

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

Create an endpoint behavior to load this inspector:

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)
    {
    }
}

Finally add this behavior to the 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());
    }
}

The above example works on my side. I could see the request header with Fiddler.

Karel Kral

There is better solution on client-side than Leonardo's. His solution requires to manually modify each request. Here is solution with ClientMessageInspector, which automatically adds header to each outgoing request.

1: Define MessageInspector with overrides: Bellow is the only one override method, the rest is empty.

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;
    }
...
}
  1. Bind this Message inspector to EndPointBehavior. Bellow is the only one override method, the rest is empty.

    public class CustomEndpointBehavior : IEndpointBehavior
    {
       public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
       {
          clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
       }
       ...
    }
  1. The last step is to add the new behavior to the WCF endpoint:
Endpoint.EndpointBehaviors.Add(new CustomEndpointBehavior());