Click here to Skip to main content
Click here to Skip to main content

Add custom headers to a WCF channel

By , 3 Jun 2009
 

Introduction

Very often, when designing WCF based SOA services, we run into the need of passing some information repeatedly from the client to the service.

One example would be a user identity information like user ID or the client application identifier. The WCF service needs the user ID information for logging purposes. So for each method call, you have to pass that information.

One way would be to pass it as an additional request parameter. But, each and every method call needs to have this parameter(s) repeatedly. Not a very clean solution. Also, if the data type of this parameter changes, all the method signatures and their calls need to be changed.

A better way to handle this requirement is to add this information to the WCF channel header.

Let's code

First of all, we will add the custom header in the proxy constructor. (Hope you are not using Visual Studio to generate the proxies, or your code would be lost the next time you generate it. Proxy generation using Visual Studio is OK initially when you create the service. You do not have to keep on doing it for each change to the service methods. It is very simple to go to the proxy class and do it manually.)

using System.ServiceModel;
using System.ServiceModel.Channels;

public partial class ZipServiceClient : 
       System.ServiceModel.ClientBase<IZipService>, IZipService
{
    //Proxy constructor
    public ZipServiceClient()
    {
        //Add basic information to the custom header
        AddCustomHeaderUserInformation(
           new OperationContextScope(base.InnerChannel));
    }
    
    // Scope is being passed. Note - If you have multiple service, you can move
    // this method to a common static class.
    // That way you would not have to same code all the proxy files.
    private static void AddCustomHeaderUserInformation(
                                 OperationContextScope scope)
    {
        //Add the basic userId
        MessageHeader<int> customHeaderUserID = 
          new MessageHeader<int>(<State.UserIDToken>);
        MessageHeader untypedHeaderUserID = 
          customHeaderUserID.GetUntypedHeader("UserID", 
          "CustomHeader");
}

The user ID here is being read from State(session). You would need to replace it to whatever storage location your information is in. Next, we will read the headers in our service.

using System.Runtime.Serialization;
using System.ServiceModel; 

 // Read the headers 

int userID = 
  OperationContext.Current.IncomingMessageHeaders.GetHeader<int>(
  "UserID", "CustomHeader");

Note: These headers are available anywhere behind the WCF service. You can access them on the Service implementation code and from the layer behind the service.

That's it. It is quite straightforward. I hope I didn't miss any detail. Email me if you have any questions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

RahulT07
Software Developer (Senior)
United States United States
Member
I have been designing and developing solutions on Microsoft platform for over 12 years in various roles and capacities.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 3memberChristian Amado30 Jul '12 - 4:48 
Good idea. Code missing!
QuestionYou are missing a detailmemberjbrentonprivate19 Jul '12 - 10:27 
Nothing on WSDL content for the extension.
GeneralMy vote of 2memberMarcelo Lujan [El Bebe.Net ]14 Feb '12 - 5:31 
A great idea but uncomplete!
GeneralMy vote of 5memberSandeep Ramani15 Sep '11 - 3:00 
very useful. nice article
GeneralIssue adding the custom http headers in WCF routing servicememberVivekanand H19 Apr '11 - 4:36 
I have tried all possible way to solve this issue from last 10 days. Till issue exist.
I am having the below setup.
WCF Client <===TCP Binding==> WCF Routing Service <==== basicHTTPBinding====> WCF Service
My requirement is need to add the SessionID in the Cookie in the WCF Routing service.
I am using the IClientMessageInspector in Routing service as below and adding the HttpRequestMessageProperty properly. Before returning i check that cookie is added.
However, at the WCF server side i seen that Message.Properties is not received ( blank).

Not sure what is problem.
Pupublic object BeforeSendRequest(ref System.ServiceModel.Channels.Message request,
System.ServiceModel.IClientChannel channel)
{
HttpRequestMessageProperty httpRequestMessage;
object httpRequestMessageObject;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrEmpty(httpRequestMessage.Headers[USER_COOKIEE]))
{
httpRequestMessage.Headers[USER_COOKIEE] = this.m_Session;
}
}
else
{
httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add(USER_COOKIEE, this.m_Session);
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
return null;
}
 
Also , i tried using the OperationContextScope as below , till unable to send the Custom HTTP headers at WCF service.
I checked headers in the Routing service all added headers exist, but when i see at WCF service not there. Please help me to resolve this issue.
 
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
get
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add(HttpRequestHeader.Cookie, "CookieTestValue");
using (OperationContextScope scope = new OperationContextScope(channel)) //Create scope using the channel.
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
//OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequestProperty);
//Also i added transport property as below.
OperationContext.Current.OutgoingMessageProperties.Add("TestHeader1"," TestHeaderVal 1213");
}
return null
}

 

Please let me know what is solution for this issue. Waiting for immediate reply.
-vivek
GeneralMy vote of 1membersteliodibello25 Aug '10 - 21:56 
not really clear and useful for me...
QuestionHow to add the header informationmemberMember 45016504 Mar '10 - 21:16 
// To add the custom header
IClientChannel proxy = (IClientChannel)m_ChannelFactory.CreateChannel();
 
//Add culture information
using (OperationContextScope scope = new OperationContextScope(proxy))
{
//Add the Custom Header
MessageHeader customHeaderCultureID = new MessageHeader("en-US");
 
MessageHeader untypedHeaderCultureID = customHeaderCultureID.GetUntypedHeader("CultureID", "CustomHeader");
 
OperationContext.Current.OutgoingMessageHeaders.Add(untypedHeaderCultureID);
 
proxy.ExecuteYourMethod();
}
 
proxy.Close();
 
// To retrieve the header
if( OperationContext.Current.IncomingMessageHeaders.FindHeader("CultureID", "CustomHeader") > 0)
{
return OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("CultureID", "CustomHeader");
}
 
I hope it helps
AnswerRe: How to add the header informationmemberVivekanand H15 Apr '11 - 0:11 
Hi all,
 
I am having Routing service in the IClientMessageIspector i am adding the message header.
 
MessageHeader untyped = mhg.GetUntypedHeader("token", "ns");
request.Headers.Add(untyped);
request.Properties.Add("sdsd", "asdasdasd");
 
But after sendng to server side unabel to see the added custom header.
 
Any idea whay? This is urgent one.
vivek
AnswerRe: How to add the header informationmemberMarcelo Lujan [El Bebe.Net ]14 Feb '12 - 7:56 
in you code i see you try to put the header in the HttpRequest!
 
Put the header in the
OperationContext.Current.OutgoingMessageHeaders
 
And read in the service with:
OperationContext.Current.IncomingMessageHeaders.GetHeader <string> ( "CultureID", "CustomHeader");
 
Dont forget the namespases
using System.ServiceModel;
using System.ServiceModel.Channels;
:Marcelo [El Bebe.net] Lujan
_____________________
Ing. Marcelo Lujan
Cimar
Monterrey, Mexico

GeneralMy vote of 2memberramuknavap27 Oct '09 - 13:15 
No code samples. Great idea but not fully explained.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 3 Jun 2009
Article Copyright 2009 by RahulT07
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid