Examining Header Values

I've seen that many people are accessing custom SOAP headers incorrectly. When you get a message with some SOAP headers, it's likely that at some point you will want to know the values of those headers. If the header you want is a well-known kind of header, then you may have direct access to the header as a property on the message.Headers collection. I'll use message.Headers as a bit of shorthand but you may have a variety of different access mechanisms to the same collection, such as on the Message object, through the operation context, and so on. If the header you want is not a well-known header, then you need to have some way of identifying and retrieving your custom message header.

This article is only about accessing the SOAP headers in a message. There may be other kinds of headers as well, such as HTTP headers, and there's no common access mechanism between SOAP level message headers and protocol level headers. Whenever you see the words message header in WCF, then that means a SOAP message header. Other kinds of protocol headers will be mapped by the implementation that handles that protocol. For example, the HTTP headers are attached to the message using message properties.

A message header is identified by a name and namespace. The name is the common name of the message header and the namespace is a way of avoiding conflicts between people creating names.

There are many incorrect ways of accessing the contents of a message header. You should not write out the XML of the message or message headers and try to parse out the message header value. You should not iterate or try to access into the message.Headers collection. That collection that you have access to contains information about the contract of the headers rather than the actual header values. You should not try to find free-standing instances of message headers and write out their XML or convert them to strings.

Instead, you should be using the GetHeader<T> method (if your header uses a typed object as its value) or the GetReaderAtHeader method (if you header contains unstructured XML) on the message.Headers collection to access the header values. There are many overloads depending on whether you know the name and namespace that identify the header, the index of the header, or other similar criteria. You'll notice that some of the overloads for accessing typed objects specify a serializer and some do not. The overloads where you don't specify a serializer use a default data contract serializer with some large quota value but things otherwise work the same.

Next time: Writers are Like Streams