Share via


Mystery of the Disappearing Addressing Headers

Why do the messages logged by my service show addressing headers but those headers disappear when the message is sent?

This is easy to explain once you actually look at the messages. Here's a quick test program that generates some SOAP 1.1 messages with all of the different addressing permutations.

 using System;
using System.Collections.Generic;
using System.ServiceModel.Channels;
using System.Xml;

class MyBodyWriter : BodyWriter
{
   public MyBodyWriter()
      : base(true)
   {
   }

   protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
   {
   }
}

class Program
{
   static IEnumerable<MessageVersion> Versions
   {
      get
      {
         yield return MessageVersion.Soap11;
         yield return MessageVersion.Soap11WSAddressing10;
         yield return MessageVersion.Soap11WSAddressingAugust2004;
      }
   }

   static void Main(string[] args)
   {
      foreach (MessageVersion version in Versions)
      {
         Message m = Message.CreateMessage(version, "MyApplication/Action", new MyBodyWriter());
         m.Headers.To = new Uri("localhost/service");
         Console.WriteLine("MessageVersion: {0}\n{1}\n", version, m.ToString());
      }
      Console.ReadLine();
   }
}

That generates the following set of messages:

MessageVersion: Soap11 (schemas.xmlsoap.org/soap/envelope/) AddressingNone (schemas.microsoft.com/ws/2005/05/addressing/none)

 <s:Envelope xmlns:s="schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="schemas.microsoft.com/ws/2005/05/addressing/none">MyApplication/Action</Action>
    <To s:mustUnderstand="1" xmlns="schemas.microsoft.com/ws/2005/05/addressing/none">localhost/service</To>
  </s:Header>
  <s:Body />
</s:Envelope>

MessageVersion: Soap11 (schemas.xmlsoap.org/soap/envelope/) Addressing10 (www.w3.org/2005/08/addressing)

 <s:Envelope xmlns:a="www.w3.org/2005/08/addressing" xmlns:s="schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <a:Action s:mustUnderstand="1">MyApplication/Action</a:Action>
    <a:To s:mustUnderstand="1">localhost/service</a:To>
  </s:Header>
  <s:Body />
</s:Envelope>

MessageVersion: Soap11 (schemas.xmlsoap.org/soap/envelope/) Addressing200408 (schemas.xmlsoap.org/ws/2004/08/addressing)

 <s:Envelope xmlns:a="schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:s="schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <a:Action s:mustUnderstand="1">MyApplication/Action</a:Action>
    <a:To s:mustUnderstand="1">localhost/service</a:To>
  </s:Header>
  <s:Body />
</s:Envelope>

Notice how the addressing headers in each message have a different namespace, and that that namespace matches the one in the MessageVersion? The headers that you see printed out reflect the in-memory representation of the message. The wire representation of the message will be constructed as the message is written out and some of those headers are in a namespace that has no wire representation. In particular, the To and Action headers you see in the schemas.microsoft.com/ws/2005/05/addressing/none namespace when not using addressing exist in memory but don't have any substance when the message is transmitted.

Next time: Validation Behaviors for Client and Service