Problem and Target
Many companies still have Web Services that are currently implemented with .NET 2.0's ASMX technology and their customers have tools that have have proxies created with .NET 2.0 technologies.
Normally, introducing WCF endpoints will require these tools to be re-engineered, which is a huge problem and needs to be avoided as much as possible. There is only one modification
that is considered acceptable in such a process, and that is changing the endpoint URL for the clients. That is because an ASMX Service normally has a URL like
http://host/Service.asmx and a WCF Service has http://host/Service.svc. The target is to change the service implementations without the existing client tools
knowing about it, at least in the sense that no code modifications are required.
This article discusses the problems, solutions, and possible pitfalls while trying to implement a solution for this migration process.
Prior to WCF, a .NET 2.0 web reference was created in the clients that acted as a proxy that facilitated the communication with a Web Service.
.NET3.5 introduced a new mechanism to create these proxies that are also compatible with WCF server-side technologies.
For simplicity reasons, in this article, each technology will be referred to as:
There are two ways to manage such a transition.
Making the ASMX and WCF layers act as wrapper layers to the actual functional implementation of the contract. That means that at any time two separate endpoints
will be exposed, that will redirect calls to a common function. All existing clients will connect to the old endpoint and all new clients to the new one.
Making the WCF Service act as an ASMX service.
Researching into the Problem
The easiest way to research about this problem is to recreate it in a simpler solution that reproduces the existing infrastructure and tries to achieve valid connectivity between
all parts, old and new.
For simplicity reasons, a common contract interface is created that is implemented by all services.
public interface IStringService
string StringConcat(string value1, string value2);
Two different projects are created on the ServiceLayer that provides ASMX and WCF services for the
Both service implementations are provided by a function in the common reference assembly.
Different client projects are created that provide proxy classes for the above services. One project uses
Client20 for the proxies
and the other
Client30. Every proxy class should be able to implement a common interface. At this point, all clients can connect to all services,
thus having the following combinations.
- Client20 - ASMX Service
- Client20 - WCF Service
Client30 - ASMX Service (obsolete)
- Client30 - WCF Service
The combination of Client30 - ASMX Service is obsolete.
public interface IStringServiceClient
string StringConcat(string value1, string value2);
At this point, we have met the requirements of Solution 1.
For Solution 2, the goal is to create a
WCFAsASMX service project that exposes a WCF Service implementing the
IStringService contract in order
to replace all the above Services successfully.
Client20 valid connectivity without code modifications ensures backwards compatibility.
Client30 valid connectivity without code alterations ensures that changes to WCF don't hold back the implementation for the future. (That is, we haven't just changed
the technology name in the implementation, but we can get all the current and future benefits that WCF provides.)
This can be achieved in these steps:
- '''Goal1''' with Solution 2 is achieving successful calls with changes at
Client20 URL endpoints.
- '''Goal2''' with Solution 2 is achieving successful calls without any change.
Force the wife service in the WCFAsASMX project to accept
Client20's requests. In this case, the namespace for the services
is "http://tempuri.org/" but it can be a properly specified one. Based on this namespace, the changes required are:
- Annotate the service with:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
Annotate the method in the service with:
If you are using arrays of basic types, for example,
string, then additionally annotate the Service with:
Now a Client20 can connect to the WCF Service with only an endpoint change. From http://host/Service.asmx to http://host/Service.svc.
This is achieved by making IIS service ASMX requests with WCF. These are the required changes:
- Alter the web.config file by adding in the system.web/compilation node:
System.ServiceModel.Activation, Version=22.214.171.124, Culture=neutral,
Copy the content of the SVC file in the ASMX file.
Comparing the Solutions
Both solutions come with an inherent limitation. They cannot provide WCF features to both clients without breaking backwards compatibility.
So it is important to understand that Client20 implementations should phase off as soon as possible, because they significantly limit the benefits of the technology transition.
- WCF Service implementation is kept clear of alterations that act as backwards compatible. This is a good thing everyone wants when introducing a new solution.
Existing clients need no modification.
- Two different physical sets of Service Layers are exposed and need to be maintained, that act as wrappers for the actual functional implementation.
- Existing clients don't connect to the actual WCF technology stack, thus they don't get the benefits of the new technology such as performance.
- There is a sense that two different technologies are supported for the proxy generation tools.
- Although two logical sets of Service Layers are exposed, only one actual physical is. This reduces the layers to maintain.
- Existing tools connect to the WCF stack and benefit from the advanatges of the new technology.
- Some minor alterations in the WCF Service have to be made. Although the changes seem simple enough, they are still meant for backwards compatibility and that is something
that must always be taken into account. The positive is that in the long run, once the Client20 implementations have phased off, removing these modifications is really simple.