15
votes

I'm working on a client-server application (.NET 4 WPF, WCF) that must support backwards compatibility. In other words, old clients should be compatible with new servers (and vice versa) as far as operation contracts and data contracts.

Our WCF services are hosted in IIS, and they were set up to use basicHttpBinding:

<basicHttpBinding>
   <binding name="basicHttpBinding_Configuration" maxBufferSize="2147483647"
      maxReceivedMessageSize="2147483647">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
         maxArrayLength="2147483647" />
      <security mode="None" />
   </binding>
</basicHttpBinding>

...

<service behaviorConfiguration="SampleGateway.Data.DataAccessBehavior"
   name="SampleGateway.Data.DataAccess">
   <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding_Configuration"
      contract="Sample.Data.IDataAccess" />
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      <host>
      <baseAddresses>
         <add baseAddress="http://localhost:8731/Design_Time_Addresses/SampleGateway/SampleGateway.Data.DataAccess.svc" />
      </baseAddresses>
   </host>
</service>

...

<behavior name="SampleGateway.Data.DataAccessBehavior">
   <serviceMetadata httpGetEnabled="true" />
   <serviceDebug includeExceptionDetailInFaults="false" />
   <dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>

Assume the contract is pretty basic and looks something like this:

[ServiceContract]
public interface IDataAccess
{
   [OperationContract]
   List<Data> GetData(List<int> ids, DateTime startDateTime, DateTime endDateTime);
}

Recently, I discovered that we could change our encoding from XML to binary. Combined with IIS compression, this really boosted the performance of our WCF methods such as GetData listed above.

This encoding change also required a change in the client and server WCF bindings, switching from a basicHttpBinding to a customBinding.

<customBinding >
   <binding name="binaryHttpBinding_Configuration">
      <binaryMessageEncoding maxReadPoolSize="2147483647" maxSessionSize="2147483647" maxWritePoolSize="2147483647">
         <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="2147483647"/>
      </binaryMessageEncoding>
      <httpTransport transferMode="Streamed" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" useDefaultWebProxy="true"/>
   </binding>
</customBinding>

...

<service behaviorConfiguration="SampleGateway.Data.DataAccessBehavior"
   name="SampleGateway.Data.DataAccess">
   <endpoint address="" binding="customBinding" bindingConfiguration="binaryHttpBinding_Configuration"
      contract="CEMLink.Data.IDataAccess" />
   <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
   <host>
      <baseAddresses>
         <add baseAddress="http://localhost:8731/Design_Time_Addresses/SampleGateway/SampleGateway.Data.DataAccess.svc" />
      </baseAddresses>
   </host>
</service>

...

Here's the problem. Since our software must support client/server backwards compatibility, if an old client with the old basicHttpBinding tries to hit a server with the new customBinding, the call is going to fail with a mismatch, e.g. "Content Type text/xml; charset=utf-8 was not supported by this service.... The client and service bindings may be mismatched"

Can I have two binding configurations for the same service contract - one basic and the other custom, and they both point to the same interface? How can I work around this?

2

2 Answers

16
votes

You basically need 2 endpoints for the same service exposed at different addresses and aligned with different bindings. This may help you.

0
votes

You can have 2 two different bindings for the same service contract, but you'll need to create separate service nodes in the config and you will also need separate endpoints defined. So create a new endpoint for the binary formatted service, and have the new version of the client reference it.