title: How can I deserialize a custom SOAP header in WCF?
body: <p>I'm attempting to add a custom header to all SOAP requests over WCF.  I found <a href="http://blogs.msdn.com/b/mohamedg/archive/2012/10/21/adding-custom-soap-headers-in-wcf.aspx" rel="nofollow noreferrer">this fantastic article</a> on how to do exactly this.  My <code>MessageHeader</code> class looks like this:</p>
  
  <pre><code>public class OperatorNameMessageHeader : MessageHeader
  {
      private string opName;
  
      public const string HeaderName = "OperatorNameMessageHeader";
      public const string HeaderNamespace = "http://schemas.microsoft.com/scout";
  
      public override string Name { get { return HeaderName; } }
      public override string Namespace { get { return HeaderNamespace; } }
  
      public string OperatorName
      {
          get { return opName; }
          set { opName = value; }
      }
  
      public OperatorNameMessageHeader()
      {
      }
  
      public OperatorNameMessageHeader(string operatorName)
      {
          opName = operatorName;
      }
  
      protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
      {
          writer.WriteElementString("OperatorName", opName);
      }
  }
  </code></pre>
  
  <p>One thing the article does <em>not</em> say is how to <em>read</em> the value on the server.  According to <a href="https://stackoverflow.com/questions/18877591/how-to-read-http-request-headers-in-a-wcf-web-service">this post</a>, you can use <code>OperationContext.Current.IncomingMessageHeaders</code> to read these headers.  When I look at these <code>MessageHeaders</code> under the debugger, I see 3 headers including my custom one.  So, it's definitely showing up in the SOAP data.  However, when I call <code>GetHeader</code>:</p>
  
  <pre><code>OperatorNameMessageHeader test = msgHeaders.GetHeader&lt;OperatorNameMessageHeader&gt;(OperatorNameMessageHeader.HeaderName, OperatorNameMessageHeader.HeaderNamespace);
  </code></pre>
  
  <p>Then <code>test.OperatorName</code> is null.  Basically, I'm just getting back an empty <code>OperatorNameMessageHeader</code> object that hasn't been deserialized from the data in the SOAP.</p>
  
  <p>My next step was to run the WCF tracing tool.  When I do this, I can verify the custom header is <em>indeed</em> being sent across the wire:</p>
  
  <pre><code>&lt;MessageHeaders&gt;
     &lt;ActivityId CorrelationId="66a7c5b6-3548-4f3c-9120-4484af76b64b" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics"&gt;f9bef03b-4e7b-4e84-b327-5e79814d9933&lt;/ActivityId&gt;
     &lt;OperatorNameMessageHeader xmlns="http://schemas.microsoft.com/scout"&gt;
        &lt;OperatorName&gt;Correct Operator Name&lt;/OperatorName&gt;
     &lt;/OperatorNameMessageHeader&gt;
     &lt;To d4p1:mustUnderstand="1" xmlns:d4p1="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"&gt;http://localhost:90/IRolesAndResourcesManager&lt;/To&gt;
     &lt;Action d4p1:mustUnderstand="1" xmlns:d4p1="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"&gt;http://tempuri.org/IRolesAndResourcesManager/Authenticate&lt;/Action&gt;
  &lt;/MessageHeaders&gt;
  </code></pre>
  
  <p>So, the server <em>has</em> the data, I just can't <em>get</em> to it.  What's the solution to this problem?</p>