Posted by: adrianbega | June 3, 2010

A simple method of injecting a custom header in a WPF call

We are often required to pass critical data to some or all of the calls to our service operations. Data such as user or security tokens, special parameters, time signatures, etc. It is not recommended to pass these kind of values as parameters of the calls, the best is to separate the business logic from the context data of our services.
Adding custom headers to the calls is in this case the best solution.
The whole operation is composed of four steps:

  • Client
    • Add header to the outgoing context message
    • Call the operation
  • Service
    • Extract header data
    • Execute operation and return result

The simplest way to add a custom header to a WCF call would be to manually attach it to each call’s OperationContext.

Inside the client, we assume we already added a reference to the service name, MyServiceRef

The header can be added to the call by overloading the constructor of the MyServiceRef.MyServiceClient in a custom class.

public class MyService : MyServiceClient
{
//Init service and attach custom header
public MyService(string customHeader) : base()
{
MessageHeader header
= MessageHeader.CreateHeader(
HeaderId.HeaderName,
HeaderId.HeaderNS,
customHeader
);
OperationContextScope scope =
new OperationContextScope(this.InnerChannel);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
}
}

When calling asynchronously GetHeader() function of MyService asynchronously from the client application, it is critical to assign the event inside the using statement to keep the integrity of the call and therefore to correctly attach the custom header to the context, before the actual operation call.

//call service and attach the header
using (MyService client = new MyService(textBox1.Text))
{
client.GetHeaderCompleted +=
new EventHandler<MyServiceRef.GetHeaderCompletedEventArgs>
(client_GetHeaderCompleted); client.GetHeaderAsync();
}

Inside the WCF service, the extraction of the header from the current OperationContext can be done as following:

static string GetHeaderInfo()
{
System.ServiceModel.Channels.MessageHeaders headers =
OperationContext.Current.IncomingMessageHeaders;
return headers.GetHeader<string>(
HeaderId.HeaderName,
HeaderId.HeaderNS);
}

Headers are usually used to pass sensitive data, so to assure their integrity, I can think of a few things to recommend:

  • if possible try to generate the content of the header inside the service (following a login function for example)
  • try using at least a basic encryption system on the content of the header

    Source code for this post is included here.

Adrian

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: