1
votes

I have the following CustomeBinding in a WCF's Web.config file

 <?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>

          <bindings>
            <customBinding>
                <binding name="notSecureBinding">
                    <textMessageEncoding messageVersion="Soap12" />
                    <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                </binding>
                <binding name="SecureBinding">
                   <textMessageEncoding messageVersion="Soap12" />
                   <httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="http://ServerName.myDomain.org/ADSearcher/Service1.svc"
                      binding="notSecureBinding"
                      bindingConfiguration="notSecureBinding"
                      contract="myNamespace.Contract1"
                      name="notSecureBinding" />

            <endpoint address="http://ServerName.myDomain.org/ADSearcher/Service1.svc"
                      binding="SecureBinding"
                      bindingConfiguration="SecureBinding"
                      contract="myNamespace.Contract1"
                      name="SecureBinding" />
        </client>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
          </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
</configuration>

Notice that i'm explicitly setting the messageVersion to Soap12, but when i call the service in the code below, i get an error message which seems to suggest that the service expects Soap11, which i'm finding strange.

This is the code

 HttpTransportBindingElement httpTransport = new HttpTransportBindingElement() { MaxBufferSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue };
 TextMessageEncodingBindingElement TextMessage = new TextMessageEncodingBindingElement() { MessageVersion = System.ServiceModel.Channels.MessageVersion.Soap12 };
 CustomBinding customBinding = new CustomBinding(TextMessage, httpTransport);
 EndpointAddress endpointAddress = new EndpointAddress("http://ServerName.myDomain.org/ADSearcher/Service1.svc");
 IService1 ADUser = new ChannelFactory<IService1>(customBinding, endpointAddress).CreateChannel();

 DataTable dt = ADUser.GetUserList(strUserName, strFirstName, strLastName, strEmail, domain);

if i i call the above code with "MessageVersion.Soap12" i get the below error

Content Type application/soap+xml; charset=utf-8 was sent to a service expecting text/xml; charset=utf-8. The client and service bindings may be mismatched.

But if i set the MessageVersion to "MessageVersion.Soap11" (which now differs from Soap11 that i have the web.config binding), the code is executed successfully with out any mismatch.

I'm not understanding why. MY preference is to to use MessageVersion.Soap12 with https support.

1
Do you have an explicit endpoint defined for the service? If you don't, most likely the service is using a default endpoint with a default binding (basicHttpBinding - which is Soap 1.1). - Tim

1 Answers

2
votes

It's possible (based on the posted code) that the service is not using the defined configuration. If the "notSecureBinding" is not explicitly assigned to an endpoint (via the bindingConfiguration) or set as the default binding, it won't be used by the service and you will get (by default) a basicHttpBinding endpoint which is, as you've discovered, SOAP 1.1.

There are a couple of ways around this. First, you can declare an endpoint (if you don't already have one) and assign the binding configuration (this would be in the service's config file).

<system.serviceModel>
   <bindings>
     <customBinding>
       <binding name="notSecureBinding">
         <textMessageEncoding messageVersion="Soap12" />
         <httpTransport maxReceivedMessageSize="2147483647" 
                        maxBufferSize="2147483647" />
       </binding>
    </customBinding>
  </bindings>
  <services>
    <service name="MyServiceName">
      <endpoint address="" binding="customBinding"
                bindingConfiguration="notSecureBinding"
                contract="MyService.IMyService" />
    </service>
  </services>
</system.serviceModel>

The second way is to make the configuration the default configuration and assign it to a given protocol (scheme), though it may not be a good solution if you are going to have multiple configurations.

For the second way, define the configuration without the name attribute:

<system.serviceModel>
   <bindings>
     <customBinding>
       <binding>
         <textMessageEncoding messageVersion="Soap12" />
         <httpTransport maxReceivedMessageSize="2147483647" 
                        maxBufferSize="2147483647" />
       </binding>
    </customBinding>
  </bindings>
</system.serviceModel>

Since you're using a customBinding, you would also update the <protocolMapping> in the `' section to reflect this:

<protocolMapping>
  <add binding="customBinding" scheme="http" />
</protocolMappings>

Either approach will result in your service picking up the correct binding configuration.