Phased Migration From ASMX to WCF
This question came up on an internal list recently (rephrasing the question slightly):
I have an ASMX service that is already exposed and is being consumed by a variety of user agents (mobile devices, windows forms, Java clients, etc). I want to change the service to use WCF without affecting existing clients. Is this possible?
Turns out there is a pretty cool way to handle this. Remember Kenny's double-decorator post? You can take your existing ASMX and overlay WCF attributes on the WebServiceAttribute decorated class and the WebMethodAttribute decorated operations. Your code-behind looks like this:
using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ServiceModel;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ServiceContract(Namespace="http://tempuri.org")]
public
class
WebService : System.Web.Services.WebService
{
[WebMethod]
[OperationContract]
public
string HelloWorld(string name)
{
return
string.Format("Hello, {0}",name);
}
}
This change allows you to continue using an ASMX file that points to your code-behind to continue using the ASMX framework, or introduce a SVC file that enables WCF hosting. You also need to introduce into your config file the system.serviceModel configuration data:
<?xml
version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service
name="WebService" behaviorConfiguration="returnFaults">
<endpoint
binding="basicHttpBinding"
contract="WebService"/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior
name="returnFaults">
<serviceDebug
includeExceptionDetailInFaults="true"/>
<serviceMetadata
httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Once you are confident that WCF is kicking ASMX's butt in performance and manageability, the next step is to cut over to WCF. Just remap the BuildProvider for ASMX to use System.ServiceModel instead.
<system.web>
<compilation
debug="true">
<buildProviders>
<remove
extension=".asmx"/>
<add
extension=".asmx"
type="System.ServiceModel.Activation.ServiceBuildProvider, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</buildProviders>
</compilation>
</system.web>
If you want to confirm that this is, in fact, using WCF now instead of ASMX, just point to the WSDL endpoint and notice that the friendly description page directs to use svcutil to generate proxy… and of course, we all know that svcutil is the WCF version of wsdl.exe!
Thanks to Ram Poornalingam for pointing out this really cool capability.