Monday, June 29, 2015

How to: Migrate ASP.NET Web Service Code to the Windows Communication Foundation

How to: Migrate ASP.NET Web Service Code to the Windows Communication Foundation

The following procedure describes how to migrate an ASP.NET Web Service to Windows Communication Foundation (WCF).

Procedure

To migrate ASP.NET Web service code to WCF

  1. Ensure that a comprehensive set of tests exist for the service.
  2. Generate the WSDL for the service and save a copy in the same folder as the service’s .asmx file.
  3. Upgrade the ASP.NET Web service to use .NET 2.0. First deploy the .NET Framework 2.0 to the application in IIS, and then use Visual Studio 2005 to automate the code conversion process, as documented in Step-By-Step Guide to Converting Web Projects from Visual Studio .NET 2002/2003 to Visual Studio 2005. Run the set of tests.
  4. Provide explicit values for the Namespace and Name parameters of the WebService attributes if they are not provided already. Do the same for the MessageNameparameter of the WebMethodAttribute. If explicit values are not already provided for the SOAPAction HTTP headers by which requests are routed to methods, then explicitly specify the default value of the Action parameter with a SoapDocumentMethodAttribute.
    [WebService(Namespace = "http://tempuri.org/", Name = "Adder")]
    public class Adder
    {
         [WebMethod(MessageName = "Add")]
         [SoapDocumentMethod(Action = "http://tempuri.org/Add")]
         public double Add(SumInput input)
         {
              double sum = 0.00;
              foreach (double inputValue in input.Input)
              {
                  sum += inputValue;
              }
          return sum;
         }
    }
    
  5. Test the change.
  6. Move any substantive code in the bodies of the methods of the class to a separate class that the original class is made to use.
    [WebService(Namespace = "http://tempuri.org/", Name = "Adder")]
    public class Adder
    {
         [WebMethod(MessageName = "Add")]
         [SoapDocumentMethod(Action = "http://tempuri.org/Add")]
         public double Add(SumInput input)
         {
              return new ActualAdder().Add(input);
         }
    }
    
    internal class ActualAdder
    {
         internal double Add(SumInput input)
         {
              double sum = 0.00;
              foreach (double inputValue in input.Input)
              {
                  sum += inputValue;
              }
          return sum;
         }
    }
    
  7. Test the change.
  8. Add references to WCF assemblies System.ServiceModel and System.Runtime.Serialization to the ASP.NET Web service project.
  9. Run ServiceModel Metadata Utility Tool (Svcutil.exe) to generate a WCF client class from the WSDL. Add the generated class module to the solution.
  10. The class module generated in the preceding step contains the definition of an interface.
    [System.ServiceModel.ServiceContractAttribute()]
    public interface AdderSoap
    {
         [System.ServiceModel.OperationContractAttribute(
          Action="http://tempuri.org/Add", 
          ReplyAction="http://tempuri.org/Add")]
         AddResponse Add(AddRequest request);
    }
    
    Modify the definition of the ASP.NET Web service class so that the class is defined as implementing that interface, as shown in the following sample code.
    [WebService(Namespace = "http://tempuri.org/", Name = "Adder")]
    public class Adder: AdderSoap
    {
         [WebMethod(MessageName = "Add")]
         [SoapDocumentMethod(Action = "http://tempuri.org/Add")]
         public double Add(SumInput input)
         {
              return new ActualAdder().Add(input);
         }
    
         public AddResponse Add(AddRequest request)
         {
            return new AddResponse(
            new AddResponseBody(
            this.Add(request.Body.input)));
         }
    }
    
  11. Compile the project. There may be some errors due to the code generated in step nine that duplicated some type definitions. Repair those errors, usually by deleting the pre-existing definitions of the types. Test the change.
  12. Remove the ASP.NET-specific attributes, such as the WebServiceWebMethodAttribute and SoapDocumentMethodAttribute.
    public class Adder: AdderSoap
    {
         public double Add(SumInput input)
         {
              return new ActualAdder().Add(input);
         }
    
         public AddResponse Add(AddRequest request)
         {
              return new AddResponse(
             new AddResponseBody(
            this.Add(request.Body.input)));
         }
    }
    
  13. Configure the class, which is now a WCF service type, to require WCF ASP.NET compatibility mode if the ASP.NET Web service relied on any of the following:
    • The HttpContext class.
    • The ASP.NET Profiles.
    • ACLs on .asmx files.
    • IIS authentication options.
    • ASP.NET impersonation options.
    • ASP.NET globalization.
    [System.ServiceModel.AspNetCompatibilityRequirements(
      RequirementsMode=AspNetCompatbilityRequirementsMode.Required)]
    public class Adder: AdderSoap
    
  14. Rename the original .asmx file to .asmx.old.
  15. Create a WCF service file for the service, give it the extension, .asmx, and save it into the application root in IIS.
    <%@Service Class="MyOrganization.Adder" %>
    <%@Assembly Name="MyServiceAssembly" %> 
    
  16. Add a WCF configuration for the service to its Web.config file. Configure the service to use the <basicHttpBinding>, to use the service file with the .asmx extension created in the preceding steps, and to not generate WSDL for itself, but to use the WSDL from step two. Also configure it to use ASP.NET compatibility mode if necessary.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
     <system.web>
      <compilation>
      <buildProviders>
       <remove extension=".asmx" />
       <add extension=".asmx" 
        type=
        "System.ServiceModel.Activation.ServiceBuildProvider,
        T:System.ServiceModel, Version=2.0.0.0, 
       Culture=neutral, 
       PublicKeyToken=b77a5c561934e089" />
      </buildProviders>
      </compilation>
     </system.web>
     <system.serviceModel>
      <services>
      <service name="MyOrganization.Adder "
        behaviorConfiguration="AdderBehavior">
       <endpoint 
        address="”
        binding="basicHttpBinding"
        contract="AdderSoap "/>
       </service>
      </services>
      <behaviors>
      <behavior name="AdderBehavior">
       <metadataPublishing 
        enableMetadataExchange="true" 
        enableGetWsdl="true" 
        enableHelpPage="true" 
        metadataLocation=
        "http://MyHost.com/AdderService/Service.WSDL"/>
      </behavior>
      </behaviors>
      <serviceHostingEnvironment 
       aspNetCompatibilityEnabled ="true"/>
     </system.serviceModel>
    </configuration>
    
    
  17. Save the configuration.
  18. Compile the project.
  19. Run the set of tests to make sure all the changes work.

No comments:

Post a Comment