Manipulating HTTP Headers in your WCF Message

I was going to write a quick note about how to suppress Expect 100-Continue as a result of this forum post. But it seems no one’s covered the background of WCF best practices for manipulating HTTP headers in general. So first, this post 🙂

Back in Beta 2, we stepped up our first class HTTP support by allowing WCF users to access and manipulate the HTTP headers that are sent on the wire. The programming model interface to this feature is through two Message Properties: HttpRequestMessageProperty (for HTTP requests) and HttpResponseMessageProperty (for HTTP responses, as you might expect). They are represented as Message Properties and not Message Headers since they are transport-specific information that is stored “outside” of the Message. Message Headers require an infoset-based representation that is included in serialization over all transports.

Using the HTTP-based Message Properties is very straightforward. First, you setup the contents of your Property. Then you attach it to your outgoing OperationContext or to your outgoing Message (if you are using the Message programming model directly). For example, if I wanted to send a GET request through WCF, I would do the following:

HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Method =
"GET";
httpRequestProperty.SuppressEntityBody =
true;
httpRequestProperty.Headers.Add(HttpRequestHeader.UserAgent, "Kenny's Client");

using (OperationContextScope scope = new OperationContextScope(myClient.InnerChannel))
{
  
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
  myClient.CallGetMethod();
}

For incoming requests/responses, you can look up the HTTP-specific information by looking for the Property on your incoming context:

HttpRequestMessageProperty httpRequestProperty = null;
object propertyValue = null;

if (OperationContext.Current.IncomingMessageProperties.TryGetValue(HttpRequestMessageProperty.Name, out propertyValue))
{
  httpRequestProperty = (
HttpRequestMessageProperty)propertyValue;
}

If this property is non-null (note that you could be accessing a Message that came in over a non-HTTP transport), then it will faithfully represent the information associated with the HTTP-specific data that was associated with this request. The above approach also applies to HTTP responses. The difference is that you use the HttpResponseMessageProperty class, and the non-header items that you can manipulate include Status Code and Status Description (rather than Verb and Query String on the request).

9 thoughts on “Manipulating HTTP Headers in your WCF Message

  1. Pingback: kennyw.com » Blog Archive » Suppressing Expect 100-Continue on your Requests

  2. Marshall Brooke

    Hi Kenny,

    Do you know why the Cache-Control header is always overwritten with plain ol “private” no matter what you set it as.

    best

    Marshall

    Reply
  3. Kenny

    Is this on your request or response? I would recommend posting on the WCF forum for this question.

    Reply
  4. Saran

    Hi,
    When I tried your code snippet, the connection is getting closed abruptly. Using the wcftestviewer.exe, I
    am seeing the following details in the log file.
    The Exception type: EndpointNotFoundException. The message is There was no channel that could accept the message with action.

    The warning message says that,
    The incoming message is not part of the existing security session.

    Any help?

    Thanks,
    Saran

    Reply
  5. Steven Pack

    Hi Kenny,

    Thanks for the sample. Is there any way to have that code execute for every call to the client? I’m trying to do exactly what you are doing there, but with an interceptor/inspector/behavior defined in configuration.

    Steve

    Reply
  6. Kenny

    Saran, does your code work if you aren’t adding the HTTP header? This doesn’t sound like an HTTP-related issue.

    Steve, you can add a ClientMessageInspector via a behavior to do what you intend.

    Reply
  7. Pingback: Adding a Message Header without using a MessageContract « Sajay's Weblog

  8. vivek

    Hi,
    I tried to add the custom HTTP header in the WCF routing service, the code is same as above. However this is found that added HTTP header was deleted in the WCF service.

    Any help and suggestions? This is urgent one.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *