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?