Click here to Skip to main content
Click here to Skip to main content

WCF Backwards Compatibility and Versioning Strategies – Part 1

, 6 Mar 2012
Rate this:
Please Sign up or sign in to vote.
Several aspects of WCF Data Contract and Service Contract versioning and the practices adopted for providing backwards compatibility to contracts.

Introduction

The article illustrates the several aspects of WCF Data Contract and Service Contract versioning and the practices adopted for providing backwards compatibility to contracts. Once the service is developed and rolled over to production, any changes in contracts should be backwards compatible so that existing clients are not affected when changes are deployed. We will explore the effects of changes in Data Contract and Service contracts and try to adopt a versioning strategy depending on the scenario. In the first part of this article, we will explore the WCF framework’s behavior in different cases of versioning of operations in Service Contracts.

Backwards Compatibility Across Contracts

Modification in a WCF service can happen in Data Contracts or in the operations of Service Contracts. In both cases, by default, WCF is version tolerant. The framework tries its best to serve existing clients with backwards compatibility. Let’s explore the different cases through an example. In order to explore WCF’s backwards compatibility behavior, we will develop a simple WCF service project. The WCF service has a single method GetData().

Implementing a WCF Service

In order to explore WCF’s backwards compatibility behavior, we will develop a simple WCF service project. The WCF service has a single method GetData() which has a parameter of “integer” type and returns “string”.

The service implementation is as follows:

Once you are done with the development of the WCF service, Right click -> View in Browser on the file MyService.svc in order to check the WSDL generated by the WCF service.

Develop a console application in order to test the service.

Right click on References->Add Service Reference. Click on Discover or type the service URL in the Address box. Once you click on OK, the stub code will be generated. Now call the service in the console application using the following code:

Run the console application. The following output should be generated:

Modification of Service Contracts

Now let’s check the behavior of the client in the case of modification of Service Contracts:

Case 1: Adding new parameters to the operation signature

Modify the service method GetData(). Add a new “interger” parameter to the method. Also, let’s change the service implementation.

Here is the modified Service Contract:

Modified Service implementation: We have added the newly passed parameter with the existing one.

Build the service.

Now run the existing consumer client console application without updating the service reference. We want to call the service using the old stub code and method signature. You should get the following output:

We can see the existing client of the service remains unaffected on adding new parameters to the service method. Actually, new parameters are initialized to default values in the service. In our case, since we have introduced a new “integer” type parameter, its default value is “0”. So the value “0” is used as the value of the new “integer” type parameter at the service end, while the service is called by the old method signature.

Case 2: Removing parameters from an operation signature

Modify the service method GetData(). Remove both parameters. Also, let’s change the service implementation.

Modified Service Contract:

Modified Service implementation: We have removed both parameters from the service.

Build the service.

Now run the existing consumer client console application without updating the service reference. We want to call the service using the old stub code and method signature. You should get the following output:

We can see the existing client of the service remains unaffected on removing parameters to the service method. Actually, superfluous parameters passed by clients are ignored at the service end and this results in data lost at the service.

Case 3: Modifying parameter types of operations

Modify the service method GetData(). In order to modify the parameter type against the existing client-side stub method signature, let’s add a new “string” parameter to the method. Also, let’s change the service implementation.

Modified Service Contract:

Modified Service implementation: We have removed both parameters from the service.

 

Build the service.

Now run the existing consumer client console application without updating the service reference. We want to call the service using the old stub code and method signature. You should get the following output:

The existing client application runs but it fails to display any value passed by the caller. Actually, in this case, the result is unexpected. An exception is supposed to be thrown if the incoming type from the client cannot be converted to the parameter data type.

Case 4: Modifying return value types

Modify the service method GetData() in order to return a “integer” type. Also, change the service implementation.

Modified Service Contract:

Modified Service implementation: We have removed both parameters from the service.

Build the service.

Now run the existing consumer client console application without updating the service reference. We want to call the service using the old stub code and method signature. You should get the following output:

The existing client application runs and displays the value passed by the caller. Again, in this case, the result is unexpected. An exception is supposed to be thrown if the return value from the service cannot be converted to the expected data type in the client version of the operation signature. Our existing client code calls the service method with the value 4. At the service end, an “integer” value 4 is returned. Now, the expected return type at the client end is “string”. So “integer” 4 has been converted to “string” 4.

Case 5: Adding new operations

Add a new service method GetNewData() and implement the same at the service end.

New Service method:

Service implementation:

Build the service.

Now run the existing consumer client console application without updating the service reference. We want to call the service using the old stub code and method signature. You should get the following output:

So the existing client remains unaffected and would not invoke operations which are totally unknown.

Case 6: Removing existing operations

Remove the existing service method GetData(). Now the service has the only method GetNewData().

Commenting the existing Service method:

 

Commenting the existing implementation:

Build the service.

Now run the existing consumer client console application without updating the service reference. As far as the old stub code at client side is concerned, the GetData() method is being called. The following error should occur:  

In this case, messages sent by the client to the service are considered to be using an unknown action header. As a result, an exception is thrown.

I have tried to discuss some possible cases of versioning of operations in the Service Contracts. In the next part of the article, I will explore WCF framework’s behavior in different cases of versioning of Data Contracts.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Kausik J. Nag
Architect
India India
No Biography provided

Comments and Discussions

 
QuestionIn case 4, my console application displays an output of 0 instead of passed value - 4 PinmemberMember 427678829-Jan-14 2:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 6 Mar 2012
Article Copyright 2012 by Kausik J. Nag
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid