Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Migrating ASMX Services to WCF Services

4.67/5 (7 votes)
17 Jan 2012CPOL5 min read 60.1K   1.4K  
Creating a WCF Service to replace existing ASMX Services.

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.

Terminology

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:

  • Client20
  • Client30

Proposed Solutions

There are two ways to manage such a transition.

Solution 1

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.

Solution 2

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.

Server Side

For simplicity reasons, a common contract interface is created that is implemented by all services.

C#
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 IStringService contract.

Both service implementations are provided by a function in the common reference assembly.

Client Side

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.

C#
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.

Goal 1

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:
  • C#
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  • Annotate the method in the service with:
  • C#
    [WebMethod]
    [OperationContract(Action=@"http://tempuri.org/StringConcat")]
  • If you are using arrays of basic types, for example, string[], then additionally annotate the Service with:
  • C#
    [XmlSerializerFormat]

    Now a Client20 can connect to the WCF Service with only an endpoint change. From http://host/Service.asmx to http://host/Service.svc.

Goal 2

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:
  • C#
    <buildProviders>
        <remove extension=".asmx">
        <add extension=".asmx" 
          type="System.ServiceModel.Activation.ServiceBuildProvider, 
                System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, 
                PublicKeyToken=31bf3856ad364e35" />
    </buildProvider>
  • 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.

Solution 1

Positives

  • 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.

Negatives

  • 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.

Solution 2

Positives

  • 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.

Negatives

  • 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.

License

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