ASMX to WCF migration

Posted in .NET,WCF by Juan Wajnerman on the May 31st, 2007

In the last weeks I faced a real world example of an ASMX to WCF migration. The existing services has been relying in many of the features available in ASMX, and a complete rewrite would not be an option.

Kenny Wolf describes in a post how to reuse an implementation of an ASMX Web Service, “double-decorating” the classes to support both ASMX and WCF with the same sources.

Kirk Allen Evans extends that idea allowing the clients remain unchanged in a first phase. That means the web services’ URL remain with the same .asmx extension replacing the ASP.NET build provider:

<buildProviders>
  <remove extension=".asmx"/>
  <add extension=".asmx" type="System.ServiceModel.Activation.ServiceBuildProvider, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</buildProviders>

Based on my experience, I can add some comments:

1. Action names

The default action names that WCF assigns for each operation is different than ASMX ones. ASMX uses the namespace appended by the message name, while WCF uses the namespace, the service name and the operation name. This means that if you want to be fully compatible with old clients, you have to specify the Action name:

[WebService(Namespace = "http://mynamespace/")]
[ServiceContract(Namespace = "http://mynamespace/")]
public class MyService
{
   [WebMethod]
   [OperationContract(Action = "http://mynamespace/TheWebMethod")]
   public void TheWebMethod()
   {
      // . . .
   }
}

2. Message names

If you used the MessageName argument for a web method, then you have to specify the corresponding Name argument in the operation contract. Also, the action name must be modified:

[WebService(Namespace = "http://mynamespace/")]
[ServiceContract(Namespace = "http://mynamespace/")]
public class MyService
{
   [WebMethod(MessageName = "MyWebMethod")]
   [OperationContract(Action = "http://mynamespace/MyWebMethod", Name = "MyWebMethod")]
   public void TheWebMethod()
   {
      // . . .
   }
}

3. Xml serialization

In the most common cases you also created your own “data contracts” for ASMX, creating Xml serializable clases. In order to support the same serialization you have to add the XmlSerializerFormat attribute:

[WebService(Namespace = "http://mynamespace/")]
[ServiceContract(Namespace = "http://mynamespace/")]
[XmlSerializerAttribute]
public class MyService
{
   [WebMethod]
   [OperationContract(Action = "http://mynamespace/TheWebMethod")]
   public MyDataType TheWebMethod()
   {
      // . . .
   }
}

4. ASP.NET compatibility

In those cases where you used ASP.NET specific features, or just for example want to have access to the current HttpContext and don’t want to change all the source code to make it in the WCF way, you can take advantage of the ASP.NET compatibility mode of WCF.

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<system.serviceModel>

The problem with this mode, is that if you replaced the .asmx build provider as I mention before and pointed by Kirk your services will fail miserably with an error like this:

Unable to cast object of type 'System.Web.Compilation.BuildResultCustomString'
to type 'System.Web.Compilation.BuildResultCompiledType'.

Fortunately, there is a very simple solution for this. Just replace the .asmx HTTP handler with the WCF one:

<httpHandlers>
  <remove path=".asmx" verb="*" />
  <add path="*.asmx" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false" />
</httpHandlers>

There are also some other important points to take into account in order to be fully compatible with old clients. For example, ASMX allows thin clients to invoke services using HTTP GET and/or PUT request with arguments encoded in the query string and the request body respectively. There are some improvements for this in Orcas that would support this out of the box, but in order to be fully compatible, all this should be supported by the same endpoint at the same time without forgetting the SOAP protocol. I had to deal with this also, but that gives enough material for a future post :) .

3 Responses to 'ASMX to WCF migration'

Subscribe to comments with RSS or TrackBack to 'ASMX to WCF migration'.

  1. SYEDHANIF said,

    on August 31st, 2007 at 2:23 am

    Migration web services to wcf services

    Framework 3.0


  2. on April 25th, 2008 at 5:22 pm

    [...] Artikel om samexistens och migrering av och med ASMX [...]


  3. on August 1st, 2008 at 8:38 pm

    [...] found a good article about replacing ASMX web wervice with WCF web service here (ASMX to WCF migration). Very cool, and my client application do not need to be [...]

Leave a Reply