Change the Service Contract without Affecting the Existing Client

In this post, I will go say some tips regarding change the service contract without affecting the existing client. Lets we see this through a sample. It is my service code and my configuration in the service.

Service Contract with one operation contract:

  1. [ServiceContract]  
  2. public interface IHelloService  
  3. {  
  4.     [OperationContract]  
  5.     string SayHello(string name);  
  6. }  
  7. Service Implementation  
  8. public class HelloService: IHelloService  
  9. {  
  10.     public string SayHello(string name)  
  11.     {  
  12.         return "Hello " + name;  
  13.     }  
  14. }  
The Configuration details:
  1. <system.serviceModel>  
  2.     <services>  
  3.         <service name="ServiceLib.HelloService" behaviorConfiguration="servicemex">  
  4.             <endpoint address="IHelloService" binding="basicHttpBinding" contract="ServiceLib.IHelloService"></endpoint>  
  5.             <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>  
  6.             <host>  
  7.                 <baseAddresses>  
  8.                     <add baseAddress="http://localhost:8080" /> </baseAddresses>  
  9.             </host>  
  10.         </service>  
  11.     </services>  
  12.     <behaviors>  
  13.         <serviceBehaviors>  
  14.             <behavior name="servicemex">  
  15.                 <serviceMetadata httpGetEnabled="true" /> </behavior>  
  16.         </serviceBehaviors>  
  17.     </behaviors>  
  18. </system.serviceModel>  
I captured it in a console application the output will be like this.
  1. ServiceRef.HelloServiceClient client = new ServiceRef.HelloServiceClient();  
  2.   
  3. Console.WriteLine(client.SayHello("Sakthikumar"));  
Output:

Hello sakthikumar

If you have any doubt regarding creating service and capture in the client application, please refer this article.

If we make changes the service contract or operation contract after given to the client. It will throw the exception in the client application the client will not able access the service.

The changed service is like this code,
  1. [ServiceContract]  
  2. public interface IHelloServiceUpdated  
  3. {  
  4.     [OperationContract]  
  5.     string SayHello(string name);  
  6. }  
  7. public class HelloService: IHelloServiceUpdated  
  8. {  
  9.     public string SayHello(string name)  
  10.     {  
  11.         return "Hello " + name;  
  12.     }  
  13. }  
The client will throw the exception like this,

An unhandled exception of type 'System.ServiceModel.ActionNotSupportedException' occurred in mscorlib.dll.

Additional information

The message with Action 'http://tempuri.org/IHelloService/SayHello' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

To resolve this problem, the WCF provide one way. That specifies the name to all contracts. The name attribute is available in the all contracts. For our sample, I go to specify the name to both service and operation contract here. The code will be,
  1. [ServiceContract(Name = "IHelloService")]  
  2. public interface IHelloServiceUpdated  
  3. {  
  4.     [OperationContract(Name = "SayHello")]  
  5.     string SayHello(string name);  
  6. }  
If we access the service now, it will not throw any exception to existing client. Please feel free if you have any doubt regarding this.