title: SOAP Version Returned in WSDL from WCF Endpoint with Custom Binding Does Not Match Config
body: <p>We've got an existing WCF endpoint that currently uses the <code>basicHttpBinding</code> with the default SOAP 1.1 binding for one endpoint. It is called by a .NET Compact Framework 3.5 client application that we control. We want some customized logging, including the number of bytes on the wire for both requests and responses. To get this, I'm developing a custom MessageEncoder and IDispatchMessageInspector with the related custom bindings in configuration. That's all working fine and the client is able to call the endpoint without issue using a proxy class that was generated before I made my changes. The problem I'm having is that when I attempt to regenerate the proxy class using NetCFSvcUtil.exe, it's failing because the WSDL says that the endpoint is using SOAP 1.2.</p>
  <blockquote>
  <p>Error: .NET Compact Framework does not support any bindings offered by this service.</p>
  <p>CustomBinding_IAssetService: .NET Compact Framework does not support binding element option TextMessageEncodingBindingElement.MessageVersion = Soap12 (<a href="http://www.w3.org/2003/05/soap-envelope" rel="nofollow noreferrer">http://www.w3.org/2003/05/soap-envelope</a>) AddressingNone (<a href="http://schemas.microsoft.com/ws/2005/05/addressing/none" rel="nofollow noreferrer">http://schemas.microsoft.com/ws/2005/05/addressing/none</a>).</p>
  </blockquote>
  <p>So, I used a browser to look at the WSDL and it is reporting the endpoint as using SOAP 1.2.</p>
  <p>The WSDL generated for my custom binding:</p>
  <pre class="lang-xml prettyprint-override"><code>&lt;wsdl:binding name=&quot;CustomBinding_IAssetService&quot; type=&quot;tns:IAssetService&quot;&gt;
      &lt;soap12:binding transport=&quot;http://schemas.xmlsoap.org/soap/http&quot;/&gt;
  </code></pre>
  <p>The WSDL generated with the old binding:</p>
  <pre class="lang-xml prettyprint-override"><code>&lt;wsdl:binding name=&quot;BasicHttpBinding_IAssetService&quot; type=&quot;tns:IAssetService&quot;&gt;
      &lt;soap:binding transport=&quot;http://schemas.xmlsoap.org/soap/http&quot;/&gt;
  </code></pre>
  <p>Interestingly, if I replace the custom encoder in my custom binding config with a <code>&lt;textMessageEncoding messageVersion=&quot;Soap11&quot;&gt;</code> element, the WSDL contains the expected SOAP 1.1 binding:</p>
  <pre class="lang-xml prettyprint-override"><code>&lt;wsdl:binding name=&quot;CustomBinding_IAssetService&quot; type=&quot;tns:IAssetService&quot;&gt;
      &lt;soap:binding transport=&quot;http://schemas.xmlsoap.org/soap/http&quot;/&gt;
  </code></pre>
  <p>That leads me to believe that it's an issue in my custom classes. I debugged the code to look at the value of <code>MessageVersion</code> that's returned from the inner <code>TextMessageEncodingBindingElement</code> object and from my custom binding classes (<code>ThroughputEncoderBindingElement</code>, <code>ThroughputEncoderExtensionElement</code>, <code>ThroughputEncoderFactory</code>, and <code>ThroughputEncoder</code>) and it's SOAP 1.1 in all cases when the WSDL request is made.</p>
  <p>Are there any issues in my code or config here? Anything else I can try?</p>
  <h3>Original Binding</h3>
  <pre class="lang-xml prettyprint-override"><code>&lt;basicHttpBinding&gt;
      &lt;binding name=&quot;HttpBinding&quot; maxReceivedMessageSize=&quot;2147483647&quot;&gt;
          &lt;readerQuotas maxDepth=&quot;2147483647&quot; ... /&gt;
      &lt;/binding&gt;
  &lt;/basicHttpBinding&gt;
  </code></pre>
  <h3>Original Config for Service</h3>
  <pre class="lang-xml prettyprint-override"><code>&lt;service name=&quot;Company.AssetService&quot; behaviorConfiguration=&quot;DefaultServiceBehavior&quot;&gt;
      &lt;host&gt;
          &lt;baseAddresses&gt;
              &lt;add baseAddress=&quot;http://localhost:8000/Asset/service&quot;/&gt;
          &lt;/baseAddresses&gt;
      &lt;/host&gt;
      &lt;endpoint address=&quot;&quot;
                binding=&quot;wsHttpBinding&quot;
                bindingConfiguration=&quot;WsBinding&quot;
                contract=&quot;Company.IAssetService&quot; /&gt;
      &lt;endpoint address=&quot;basic&quot;
                binding=&quot;basicHttpBinding&quot;
                bindingConfiguration=&quot;HttpBinding&quot;
                contract=&quot;Company.IAssetService&quot; /&gt;
  &lt;/service&gt;
  </code></pre>
  <h3>New Binding</h3>
  <pre class="lang-xml prettyprint-override"><code>&lt;customBinding&gt;
      &lt;binding name=&quot;throughputEncoding&quot; maxReceivedMessageSize=&quot;2147483647&quot;&gt;
        &lt;throughputEncoding&gt;
          &lt;textEncoding messageVersion=&quot;Soap11&quot;&gt;
            &lt;readerQuotas maxDepth=&quot;2147483647&quot; maxStringContentLength=&quot;2147483647&quot; ... /&gt;
          &lt;/textEncoding&gt;
        &lt;/throughputEncoding&gt;
        &lt;httpTransport/&gt;
      &lt;/binding&gt;
  &lt;/customBinding&gt;
  </code></pre>
  <h3>New Config for Service</h3>
  <pre class="lang-xml prettyprint-override"><code>&lt;service name=&quot;Company.AssetService&quot; behaviorConfiguration=&quot;DefaultServiceBehavior&quot;&gt;
      &lt;host&gt;
          &lt;baseAddresses&gt;
              &lt;add baseAddress=&quot;http://localhost:8000/Asset/service&quot;/&gt;
          &lt;/baseAddresses&gt;
      &lt;/host&gt;
      &lt;endpoint address=&quot;&quot;
                binding=&quot;wsHttpBinding&quot;
                bindingConfiguration=&quot;WsBinding&quot;
                contract=&quot;Company.IAssetService&quot; /&gt;
      &lt;endpoint address=&quot;basic&quot;
                binding=&quot;customBinding&quot;
                bindingConfiguration=&quot;throughputEncoding&quot;
                contract=&quot;Company.IAssetService&quot; /&gt;
  &lt;/service&gt;
  </code></pre>
  <h3>Extension Config</h3>
  <pre class="lang-xml prettyprint-override"><code>&lt;extensions&gt;
      ...
    &lt;bindingElementExtensions&gt;
      &lt;add name=&quot;throughputEncoding&quot;
           type=&quot;Company.Infrastructure.ThroughputEncoderExtensionElement, Company, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&quot; /&gt;
    &lt;/bindingElementExtensions&gt;
  &lt;/extensions&gt;
  </code></pre>
  <h3>Classes</h3>
  <pre class="lang-c# prettyprint-override"><code>public class ThroughputEncoder : MessageEncoder
  {
      private readonly MessageEncoder innerEncoder;
      private readonly WcfMessageLogger logger;
  
      public ThroughputEncoder(MessageEncoder innerEncoder)
      {
          this.innerEncoder = innerEncoder;
          logger = new WcfMessageLogger();
      }
  
      public override string ContentType
      {
          get { return &quot;text/xml&quot;; }
      }
  
      public override string MediaType
      {
          get { return &quot;text/xml&quot;; }
      }
  
      public override MessageVersion MessageVersion
      {
          get { return innerEncoder.MessageVersion; }
      }
      ...
  }
  
  public class ThroughputEncoderFactory : MessageEncoderFactory
  {
      private readonly ThroughputEncoder throughputEncoder;
  
      public ThroughputEncoderFactory(MessageEncoder messageEncoder)
      {
          throughputEncoder = new ThroughputEncoder(messageEncoder);
      }
  
      public override MessageEncoder Encoder
      {
          get { return throughputEncoder; }
      }
  
      public override MessageVersion MessageVersion
      {
          get { return throughputEncoder.MessageVersion; }
      }
  }
  
  public class ThroughputEncoderExtensionElement : BindingElementExtensionElement
  {
      private const string TextEncodingPropertyName = &quot;textEncoding&quot;;
  
      [ConfigurationProperty(TextEncodingPropertyName)]
      public TextMessageEncodingElement TextEncoding
      {
          get { return (TextMessageEncodingElement)this[TextEncodingPropertyName]; }
          set { this[TextEncodingPropertyName] = value; }
      }
  
      protected override BindingElement CreateBindingElement()
      {
          var textBindingElement = new TextMessageEncodingBindingElement();
  
          if (TextEncoding != null)
              TextEncoding.ApplyConfiguration(textBindingElement);
  
          return new ThroughputEncoderBindingElement(textBindingElement);
      }
  
      public override Type BindingElementType
      {
          get { return typeof (ThroughputEncoderBindingElement); }
      }
  }
  
  public class ThroughputEncoderBindingElement : MessageEncodingBindingElement
  {
      private readonly MessageEncodingBindingElement innerBindingElement;
  
      public ThroughputEncoderBindingElement(MessageEncodingBindingElement innerBindingElement)
      {
          this.innerBindingElement = innerBindingElement;
      }
  
      public override IChannelFactory&lt;TChannel&gt; BuildChannelFactory&lt;TChannel&gt;(BindingContext context)
      {
          context.BindingParameters.Add(this);
          return base.BuildChannelFactory&lt;TChannel&gt;(context);
      }
  
      public override IChannelListener&lt;TChannel&gt; BuildChannelListener&lt;TChannel&gt;(BindingContext context)
      {
          context.BindingParameters.Add(this);
          return base.BuildChannelListener&lt;TChannel&gt;(context);
      }
  
      public override bool CanBuildChannelFactory&lt;TChannel&gt;(BindingContext context)
      {
          context.BindingParameters.Add(this);
          return base.CanBuildChannelFactory&lt;TChannel&gt;(context);
      }
  
      public override bool CanBuildChannelListener&lt;TChannel&gt;(BindingContext context)
      {
          context.BindingParameters.Add(this);
          return base.CanBuildChannelListener&lt;TChannel&gt;(context);
      }
  
      public override MessageEncoderFactory CreateMessageEncoderFactory()
      {
          var innerFactory = innerBindingElement.CreateMessageEncoderFactory();
          return new ThroughputEncoderFactory(innerFactory.Encoder);
      }
  
      public override BindingElement Clone()
      {
          return new ThroughputEncoderBindingElement(innerBindingElement);
      }
  
      public override T GetProperty&lt;T&gt;(BindingContext context)
      {
          return innerBindingElement.GetProperty&lt;T&gt;(context) ?? context.GetInnerProperty&lt;T&gt;();
      }
  
      public override MessageVersion MessageVersion
      {
          get { return innerBindingElement.MessageVersion; }
          set { innerBindingElement.MessageVersion = value; }
      }
  }
  </code></pre>