Adding a Message Header without using a MessageContract

Using Message contracts is quite a straight forward way of creating and adding message headers.But then again you might just want to add a header without going downt that route like this post by Kenny. You generally come across 2 scenarios where you want to add headers in every message or just for a particular set of operations that you would like to control. The code below shows you how to add headers for every operation using a Client behavior or just to a particular set calls using the OperationContextScope which would give you access to current operation context on the client side.

You can modify the outgoing message headers on using the OperationContext. If you are using a client instance(generated proxy then you can uset he inner channel ref: article) or else you can just use the channel factory and get the client channel.

Here the first operation is called without the a scoped header and the header is added only after the first call to the proxy happens. and the same operation can now access the header newly added header.

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

using System.ServiceModel.Description;

using System.ServiceModel.Channels;

using System.ServiceModel.Dispatcher;

namespace SoapHeaderSample

{

[ServiceContract]

public interface ICalculatorService

{

[OperationContract]

int Add(int a, int b);

}

public class CalculatorService : ICalculatorService

{

public int Add(int a, int b)

{

//Get the header in the operation

MessageHeaders hdrs = OperationContext.Current.IncomingMessageHeaders;

int hdrIndex = hdrs.FindHeader("BehaviorHeader", "BehaviorHeaderNS");

int scopeHdrIndex = hdrs.FindHeader("ScopedHeader", "ScopedHeaderNS");

Console.WriteLine("HeaderContent at service:" + hdrs.GetHeader<string>(hdrIndex));

if(scopeHdrIndex >=0)

Console.WriteLine("ScopedHeader Content at service:" + hdrs.GetHeader<string>(scopeHdrIndex));

return a + b;

}

}

class Program

{

static void Main(string[] args)

{

string addr = "net.tcp://localhost:5050/ServiceModelSamples";

Uri[] baseAddrs = new Uri[] { new Uri(addr) };

using (ServiceHost host = new ServiceHost(typeof(CalculatorService), baseAddrs))

{

host.AddServiceEndpoint(typeof(ICalculatorService), new NetTcpBinding(), "");

host.Open();

Console.WriteLine("Host listening at " + host.BaseAddresses[0]);

Console.ReadLine();

//Call the service

ChannelFactory<ICalculatorService> cf = new ChannelFactory<ICalculatorService>(new NetTcpBinding(), addr);

cf.Endpoint.Behaviors.Add(new EndpointBehaviorAddHeader());

ICalculatorService proxy = cf.CreateChannel();

try

{

using (OperationContextScope scope = new OperationContextScope(proxy as IClientChannel))

{

Console.WriteLine("\tResult " + proxy.Add(10, 100));

//Add the new header for this operation

Console.WriteLine("\nNew Header added.\n");

OperationContext.Current.OutgoingMessageHeaders.Add(

MessageHeader.CreateHeader("ScopedHeader", "ScopedHeaderNS", "Scoped header value"));

Console.WriteLine("\tResult " + proxy.Add(10, 100));

}

}

finally

{

IChannel c = proxy as IChannel;

if(c !=null && c.State == CommunicationState.Opened)

c.Close();

}

}

}

public class EndpointBehaviorAddHeader : IEndpointBehavior

{

public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)

{}

public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)

{

clientRuntime.MessageInspectors.Add(new MessageInspectorAddHeader());

}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)

{}

public void Validate(ServiceEndpoint endpoint)

{}

}

public class MessageInspectorAddHeader : IClientMessageInspector

{

public void AfterReceiveReply(ref Message reply, object correlationState)

{}

public object BeforeSendRequest(ref Message request, IClientChannel channel)

{

MessageHeader hrd = MessageHeader.CreateHeader("BehaviorHeader", "BehaviorHeaderNS", "BehaviorHeader header content");

request.Headers.Add(hrd);

return null;

}

}

}

}