Welcome to Windows Communication Foundation (WCF)
Top Tasks :

 

Craig McMurtry
Technical Evangelist  
Microsoft Corporation

April 19, 2006

Summary: This article compares ASP.NET Web services to the Windows Communication Foundation and explains what to do about existing and planned ASP.NET Web services now that the Windows Communication Foundation is soon to be released.  (43 printed pages)

 

ASP.NET provides .NET class libraries and tools for building Web services, as well as facilities for hosting those services within Internet Information Services (IIS).  The Windows Communication Foundation, which was code-named Indigo, provides .NET class libraries, tools and hosting facilities for enabling software entities to communicate using any protocols, including those used by Web services.  So, what are the prospects for ASP.NET Web services now that a newer, more general technology for building Web services is coming? 

This paper compares the two technologies.  It describes how ASP.NET Web service applications can be used together with Windows Communication Foundation applications.  The paper also explains both how to prepare for migrating ASP.NET Web services to the Windows Communication Foundation, and how to actually do that migration.  

For the purposes of this paper, the facilities that ASP.NET provides for building Web services are considered separately from the Web Services Enhancements for Microsoft .NET (WSE).  The prospects for applications developed using WSE will be examined elsewhere. 

The Decision Maker’s Perspective

The Windows Communication Foundation is scheduled to be released in the second half of 2006.  It has several important advantages relative to ASP.NET Web services that any organization using that earlier technology needs to consider. 

Whereas the ASP.NET Web services tools are solely for building Web services, the Windows Communication Foundation provides tools for use in any circumstance where software entities must be made to communicate with one another.  That should reduce the number of technologies that developers are required to know in order to accommodate different software communication scenarios, which should in turn reduce the cost of software development resources, as well as the time to complete software development projects. 

Even for Web service development projects, the Windows Communication Foundation supports more Web service protocols than ASP.NET Web services support.  Those protocols provide for more sophisticated solutions involving, amongst other things, reliable sessions and transactions. 

The Windows Communication Foundation supports more protocols for transporting messages than the ASP.NET Web services support.  ASP.NET Web services only support sending messages via the Hypertext Transfer Protocol (HTTP).  The Windows Communication Foundation supports sending messages via HTTP, as well as the Transmission Control Protocol (TCP), named pipes, and Microsoft Message Queuing (MSMQ).  More important, the Windows Communication Foundation can be readily extended to support additional transport protocols.  Therefore, software developed using the Windows Communication Foundation can be readily adapted to work together with a wider variety of other software, thereby increasing the potential return on the investment in it. 

The Windows Communication Foundation provides much richer facilities for deploying and managing applications than ASP.NET Web services provides.  In addition to a configuration system, which ASP.NET also has, the Windows Communication Foundation offers a configuration editor, activity tracing from senders to receivers and back via any number of intermediaries, a trace viewer, message logging, a vast number of performance counters, and support for Windows Management Instrumentation.  This rich set of administrative tools should serve to reduce operational costs, the risk of failures, and actual downtime. 

Given these potential benefits of the Windows Communication Foundation relative to ASP.NET Web services, organizations that are using, or are considering using ASP.NET Web services have several options:  

·         Simply continue to use ASP.NET Web services, and forego the benefits proffered by the Windows Communication Foundation.  Under Microsoft’s current support lifecycle policy, mainstream support for ASP.NET Web services will be provided until at least the year 2011, and extended support will be provided until at least 2016.  So, there is no great risk in continuing to use ASP.NET Web services. 

·         Keep using ASP.NET Web services with the intention of adopting the Windows Communication Foundation at some time in the future.  This paper will explain how to maximize the prospects for being able to use new ASP.NET Web service applications together with future Windows Communication Foundation applications.  It will also explain how to build new ASP.NET Web services so as to make it easier to migrate them to the Windows Communication Foundation.  However, if securing the services is important, or reliability or transaction assurances are required, or if it appears that custom management facilities will have to be constructed, then the decision to defer adopting the Windows Communication Foundation is probably mistaken.  It is designed for precisely such scenarios, and production licenses for the technology are already available. 

·         Adopt the Windows Communication Foundation for new development, while continuing to maintain their existing ASP.NET Web service applications.  This choice is very likely the optimal one.  It yields the benefits of the Windows Communication Foundation, while sparing the cost of modifying the existing applications to use it.  In this scenario, new Windows Communication Foundation applications can co-exist with existing ASP.NET applications.  Also, new Windows Communication Foundation applications will be able to use existing ASP.NET Web services, and the Windows Communication Foundation can even be used to program new operational capabilities into existing ASP.NET applications by virtue of the Windows Communication Foundation’s ASP.NET compatibility mode. 

·         Adopt the Windows Communication Foundation and migrate existing ASP.NET Web service applications to the Windows Communication Foundation.   An organization might choose this option in order to eliminate any requirement for their developers to know about ASP.NET Web services.  That would not be a good reason for this choice, though, because the prospect of eliminating support for any technologies other than the latest ones is probably chimerical.  The only good reasons for migrating would be to enhance the existing applications with features provided by the Windows Communication Foundation, or to reproduce the functionality of existing ASP.NET Web services within new, more powerful Windows Communication Foundation applications.  This paper will explain how to accomplish the migration. 

Comparing the Technologies: Purpose

The ASP.NET Web services technology was developed for building applications that send and receive messages via the Simple Object Access Protocol (SOAP) over HTTP.  The structure of the messages can be defined using XML Schema, and a tool is provided to facilitate serializing the messages to and from .NET objects.  The technology can automatically generate metadata to describe Web services in the Web Services Description Language (WSDL), and a second tool is provided for generating clients for Web services from the WSDL. 

The Windows Communication Foundation is for enabling .NET applications to exchange messages with other software entities.  SOAP is used by default, but the messages can be in any format, and conveyed via any transport protocol.  The structure of the messages can be defined using XML Schema, and there are various options for serializing the messages to and from .NET objects.  The Windows Communication Foundation can automatically generate metadata to describe applications built using the technology in WSDL, and it also provides a tool for generating clients for those applications from the WSDL. 

Comparing the Technologies: Standards

The standards supported by ASP.NET Web services are listed at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetimplementationofwebservices.asp?frame=true.  The more extensive list of standards supported by the Windows Communication Foundation are listed at http://windowssdk.msdn.microsoft.com/library/default.asp?url=/library/en-us/WCF_con/html/1f7fc4ff-30fe-4e46-adda-91caad3b06c6.asp?frame=true. 

Comparing the Technologies: Development

ASP.NET Compatibility Mode

The Windows Communication Foundation has an ASP.NET compatibility mode option by which certain Windows Communication Foundation applications can be programmed and configured like ASP.NET Web services, and will mimic their behavior.  How to opt for ASP.NET compatibility mode is explained below, and details of the exact effects of that option will be provided. 

Data Representation

The development of a Web service with ASP.NET typically begins with defining any complex data types the service is to use.  ASP.NET relies on the System.Xml.Serialization.XmlSerializer to translate data represented by .NET objects into XML for transmission to or from a service, and to translate data received as XML into .NET objects.  So, defining the complex data types that an ASP.NET service is to use requires the definition of .NET classes that the System.Xml.Serialization.XmlSerializer can serialize to and from XML.  Such classes can be written manually, of course, or generated from definitions of the types in XML Schema using the command-line XML Schemas/Data Types Support Utility, xsd.exe. 

These are the key things to know about defining .NET classes that the System.Xml.Serialization.XmlSerializer will be able to serialize to and from XML:

·         Only the public fields and properties of .NET objects will be translated into XML. 

·         Instances of collection classes can be serialized into XML only if the classes implement either the IEnumerable or ICollection interface. 

·         As a corollary, classes that implement the System.Collections.IDictionary interface, like System.Collections.Hashtable, cannot be serialized into XML. 

·         The great many attribute types in the System.Xml.Serialization namespace can be added to a .NET class and its members to control exactly how instances of the class are represented in XML. 

Windows Communication Foundation application development usually also begins with the definition of complex types.  The Windows Communication Foundation can be made to use the same .NET types as ASP.NET Web services.  It offers a better alternative, though. 

The System.Runtime.Serialization.DataContract and System.Runtime.Serialization.DataMember attributes of the Windows Communication Foundation’s System.Runtime.Serialization assembly can be added to .NET types to indicate that instances of the type are to be serialized into XML, and which particular fields or properties of the type are to be serialized.  All three of the following examples are valid:

//Example One:

[DataContract]

public class LineItem

{

    [DataMember]

    public string ItemNumber;

    [DataMember]

    public decimal Quantity;

    [DataMember]

    public decimal UnitPrice;

}

 

//Example Two:

public class LineItem

{

    [DataMember]

    private string itemNumber;

    [DataMember]

    private decimal quantity;

    [DataMember]

    private decimal unitPrice;

 

    public string ItemNumber

    {

        get

        {

            return this.itemNumber;

        }

 

        set

        {

            this.itemNumber = value;

        }

    }

 

    public decimal Quantity

    {

        get

        {

            return this.quantity;

        }

 

        set

        {

            this.quantity = value;

        }

    }

 

    public decimal UnitPrice

    {

        get

        {

            return this.unitPrice;

        }

 

        set

        {

            this.unitPrice = value;

        }

    }

}

 

//Example Three:

public class LineItem

{

    private string itemNumber;

    private decimal quantity;

    private decimal unitPrice;

 

    [DataMember]

    public string ItemNumber

    {

        get

        {

            return this.itemNumber;

        }

 

        set

        {

            this.itemNumber = value;

        }

    }

 

    [DataMember]

    public decimal Quantity

    {

        get

        {

            return this.quantity;

        }

 

        set

        {

            this.quantity = value;

        }

    }

 

    [DataMember]

    public decimal UnitPrice

    {

        get

        {

            return this.unitPrice;

        }

 

        set

        {

            this.unitPrice = value;

        }

    }

}

The System.Runtime.Serialization.DataContract attribute signifies that zero or more of a type’s fields or properties are to be serialized, while the System.Runtime.Serialization.DataMember attribute indicates that a particular field or property is to be serialized.  The System.Runtime.Serialization.DataContract attribute can be applied to a class or struct.  The System.Runtime.Serialization.DataMember attribute can be applied to a field or a property, and the fields and properties to which the attribute is applied can be either public or private.  Instances of types that have System.Runtime.Serialization.DataContract attributes are referred to as data contracts in the argot of the Windows Communication Foundation.  They are serialized into XML using the Windows Communication Foundation’s System.Runtime.Serialization.DataContractFormatter. 

How do the System.Runtime.Serialization.DataContractFormatter and the System.Runtime.Serialization.DataContract and System.Runtime.Serialization.DataMember attributes differ from the System.Xml.Serialization.XmlSerializer and the various attributes of the System.Xml.Serialization namespace?  There are many important differences. 

1.      The System.Xml.Serialization.XmlSerializer and the attributes of the System.Xml.Serialization namespace are designed to allow one to map .NET types to any valid type defined in XML Schema, and so they provide for very precise control over how a .NET type is represented in XML.  The System.Runtime.Serialization.DataContractFormatter and the System.Runtime.Serialization.DataContract and System.Runtime.Serialization.DataMember attributes provide very little control over how a .NET type is represented in XML.  One can only specify the namespaces and names used to represent the type and its fields or properties in the XML, and the sequence in which the fields and properties appear in the XML:

[DataContract(

Namespace="urn:Woodgrove:2006:January:29",

Name="LineItem")]

public class LineItem

{

    [DataMember(Name="ItemNumber",IsRequired=true,Order=0)]

    public string itemNumber;

    [DataMember(Name="Quantity",IsRequired=false,Order = 1)]

    public decimal quantity;

    [DataMember(Name="Price",IsRequired=false,Order = 2)]

    public decimal unitPrice;

}

Everything else about the structure of the XML used to represent the .NET type is determined by the System.Runtime.Serialization.DataContractFormatter. 

2.      By not permitting much control over how a .NET type is to be represented in XML, the serialization process becomes highly predictable for the System.Runtime.Serialization.DataContractFormatter, and, thereby, more amenable to optimization.   So, a practical benefit of the design of the System.Runtime.Serialization.DataContractFormatter is better performance, approximately ten percent better performance. 

3.      Comparing the following type, which has attributes for serialization with the System.Xml.Serialization.XmlSerializer,

[Serializable]

[XmlRoot(Namespace="urn:Woodgrove:2006:January:29")]

public class LineItem

{

    public string ItemNumber;

    public decimal Quantity;

    public decimal UnitPrice;

}

with this version, which has attributes for use with the System.Runtime.Serialization.DataContractFormatter:

[DataContract(Namespace="urn:Woodgrove:2006:January:29")]

public class LineItem

{

    [DataMember]

    public string ItemNumber;

    [DataMember]

    public decimal Quantity;

    [DataMember]

    public decimal UnitPrice;

}

The attributes for use with the System.Xml.Serialization.XmlSerializer do not indicate which fields or properties of the type will be serialized into XML, whereas the System.Runtime.Serialization.DataMember attribute for use with the System.Runtime.Serialization.DataContractFormatter shows explicitly which fields or properties will be serialized.  Therefore, one can say that data contracts are explicit contracts about the structure of the data that an application is to send and receive. 

4.      Whereas the System.Xml.Serialization.XmlSerializer can only translate the public members of a .NET object into XML, the System.Runtime.Serialization.DataContractFormatter can translate the members of .NET objects into XML regardless of the access modifiers of those members. 

5.      Partly as a consequence of being able to serialize the non-public members of types into XML, the System.Runtime.Serialization.DataContractFormatter has fewer restrictions on the variety of .NET types that it can serialize into XML.  In particular, it can translate into XML types like System.Collections.Hashtable that implement the Systems.Collections.IDictionary interface.  Generally, the System.Runtime.Serialization.DataContractFormatter is much more likely to be able to serialize the instances of any pre-existing .NET type into XML without one having to either modify the definition of the type or develop a wrapper for it. 

6.      However, another consequence of the System.Runtime.Serialization.DataContractFormatter being able to access the non-public members of a type is that requires full trust, whereas the System.Xml.Serialization.XmlSerializer does not. 

7.      The System.Runtime.Serialization.DataContractFormatter incorporates some support for versioning. 

·         The System.Runtime.Serialization.DataMember attribute has an IsRequired property that can be assigned a value of false for members that are added to new versions of a data contract that were not present in earlier versions, thereby allowing applications with the newer version of the contract to be able to process earlier versions. 

·         By having a data contract implement the simple System.Runtime.Serialization.IExtensibleDataObject interface, one can allow the System.Runtime.Serialization.DataContractFormatter to pass members defined in newer versions of a data contract through applications with earlier versions of the contract.   

Despite all of those differences, the XML into which the System.Xml.Serialization.XmlSerializer will serialize a type by default is semantically identical to the XML into which the System.RuntimeSerialization.DataContractFormatter will serialize a type, provided the namespace for the XML is explicitly defined.  So, this class, which has attributes for use with both of the serializers, will be translated into semantically identical XML by the System.Xml.Serialization.XmlSerializer and by the System.RuntimeSerialization.DataContractFormatter:

[Serializable]

[XmlRoot(Namespace="urn:Woodgrove:2006:January:29")]

[DataContract(Namespace="urn:Woodgrove:2006:January:29")]

public class LineItem

{

    [DataMember]

    public string ItemNumber;

    [DataMember]

    public decimal Quantity;

    [DataMember]

    public decimal UnitPrice;

}

The software development kit that accompanies the Windows Communication Foundation includes a command-line tool called the Service Model Metadata Tool, svcutil.exe.  Like the xsd.exe tool used with ASP.NET Web services, svcutil.exe can generate definitions of .NET data types from XML Schema.  Those .NET data types will be data contracts if the System.Runtime.Serialization.DataContractFormatter can emit XML in the format defined by the XML Schema; otherwise, they will be intended for serialization using the System.Xml.Serialization.XmlSerializer.  The tool, svcutil.exe, can also be made to generate XML Schema from data contracts using its /dataContractOnly switch. 

Note that although ASP.NET Web services use the System.Xml.Serialization.XmlSerializer, and the Windows Communication Foundation’s ASP.NET compatibility mode makes Windows Communication Foundation services mimic the behavior of ASP.NET Web services, the ASP.NET compatibility option does not restrict one to using the System.Xml.Serialization.XmlSerializer.  One can still use the System.Runtime.Serialization.DataContractFormatter with services running in the ASP.NET compatibility mode. 

Service Development

To develop a service using ASP.NET, it has been customary to simply add the System.Web.Services.WebService attribute to a class, and the  System.Web.Services.WebMethod attribute to any of that class’ methods that are to be operations of the service: 

[WebService]

public class Service : System.Web.Services.WebService

{

    [WebMethod]

    public string Echo(string input)

    {

        return input;

    }

}

ASP.NET 2.0 introduced the option of adding the System.Web.Services.WebService and System.Web.Services.WebMethod attributes to an interface rather than to a class, and writing a class to implement the interface:

[WebService]

public interface IEcho

{

    [WebMethod]

    string Echo(string input);

}

 

public class Service : IEcho

{

 

    public string Echo(string input)

    {

        return input;

    }

}

Using this option is to be preferred, because the interface with the System.Web.Services.WebService attribute constitutes a contract for the operations performed by the service that can be reused with various classes that might implement that same contract in different ways. 

A Windows Communication Foundation service is provided by defining one or more Windows Communication Foundation endpoints.  An endpoint is defined by an address, a binding and a service contract.  The address defines where the service is located.  The binding specifies how to communicate with the service.  The service contract defines the operations that the service can perform. 

The service contract is usually defined first, by adding System.ServiceModel.ServiceContract and System.ServiceModel.OperationContract attributes to a .NET interface:

[ServiceContract]

public interface IEcho

{

    [OperationContract]

    string Echo(string input);

}

The System.ServiceModel.ServiceContract attribute specifies that the interface defines a Windows Communication Foundation service contract, and the System.ServiceModel.OperationContract attribute indicates which, if any, of the methods of the interface define operations of the service contract. 

Once a service contract has been defined, it is implemented in a class, simply by having the class implement the interface by which the service contract is defined:

public class Service : IEcho

{

   

    public string Echo(string input)

    {

        return input;

    }

}

A class that implements a service contract is referred to as a service type in the argot of the Windows Communication Foundation. 

The next step is to associate an address and a binding with a service type.  That is typically done in a configuration file, either by editing the file directly, or by using a configuration editor provided with the Windows Communication Foundation.  Here is an example of a configuration file.   

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

      <system.serviceModel>

            <services>

                  <service name="Service ">

                        <endpoint

                              address="EchoService"

                              binding="basicHttpBinding"

                              contract="IEchoService "/>

                  </service>

            </services>

      </system.serviceModel>

</configuration>

The binding specifies the set of protocols for communicating with the application.  There are a number of predefined bindings that represent common options:

Name

Purpose

BasicHttpBinding

Interoperability with web services and clients supporting the WS-BasicProfile 1.1 and Basic Security Profile 1.0

WSHttpBinding

Interoperability with web services and clients supporting the WS-* protocols over HTTP

WSDualHttpBinding

Duplex HTTP communication, by which the receiver of an initial message will not reply directly to the initial sender, but may transmit any number of responses over a period of timemmunication via HTTP in conformity with WS-* protocols.  ation ServiceHost,  just one base address, and its schema is pecif

WSFederationBinding

HTTP communication, in which access to the resources of a service can be controlled based on credentials issued by an explicitly-identified credential provider

NetTcpBinding

Secure, reliable, high-performance communication between Windows Communication Foundation software entities across a network

NetNamedPipeBinding

Secure, reliable, high-performance communication between Windows Communication Foundation software entities on the same machine

NetMsmqBinding

Communication between Windows Communication Foundation software entities via MSMQ

MsmqIntegrationBinding

Communication between a Windows Communication Foundation software entity and another software entity via MSMQ

NetPeerTcpBinding

Communication between Windows Communication Foundation software entities via Windows Peer-to-Peer Networking

The predefined binding, System.ServiceModel.BasicHttpBinding, incorporates the set of protocols supported by ASP.NET Web services. 

Custom bindings for Windows Communication Foundation applications are easily defined as collections of the binding element classes that the Windows Communication Foundation uses to implement individual protocols.  New binding elements can be written to represent additional protocols. 

The internal behavior of service types can be adjusted using the properties of a family of classes called behaviors.  Here, the System.ServiceModel.ServiceBehavior class is used to specify that the service type is to be multithreaded:

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple]

public class DerivativesCalculatorServiceType: IDerivativesCalculator

Some behaviors, the ones with properties that programmers would want to set, like System.ServiceModel.ServiceBehavior, are attributes.  Others, the ones with properties that administrators would want to set, can be modified in the configuration of an application. 

In programming service types, frequent use is made of the System.ServiceModel.OperationContext class.  Its static Current property provides access to information about the context in which an operation is executing.  Thus, System.ServiceModel.OperationContext is similar to both the System.Web.HttpContext and System.EnterpriseServices.ContextUtil classes. 

Hosting

ASP.NET Web services are compiled into a class library assembly.  A file called the service file is provided that has the extension .asmx and contains an @ WebService directive identifying the class containing the code for the service, and the assembly in which it is located: 

<%@ WebService Language="C#" Class="Service,ServiceAssembly" %>

The service file is copied into an ASP.NET application root in IIS, and the assembly is copied into the \bin subdirectory of that application root.  The application is then accessible via the uniform resource locator (URL) of the service file in the application root. 

Aaron Skonnard has explained how to use the HttpListener class provided by the .NET Framework 2.0 to host ASP.NET Web services outside of IIS, in any .NET application (http://msdn.microsoft.com/msdnmag/issues/04/12/ServiceStation/default.aspx).  However, Skonnard himself describes the effort involved as “non-trivial” (http://msdn.microsoft.com/msdnmag/issues/06/01/ServiceStation/). 

Windows Communication Foundation services can readily be hosted within IIS 5.1 or 6.0, the Windows Activation Service (WAS) that is to be provided as part of IIS 7, and within any .NET application.  To host a service in IIS 5.1 or 6.0, the service must use HTTP as the communications transport protocol. 

To host a service within IIS 5.1 or 6.0, or within WAS one follows these steps:

1.      Compile the service type into a class library assembly. 

2.      Create a service file with a .svc extension with an @ ServiceHost directive to identify the service type:

<%@ServiceHost language=”c#” Service="MyService" %>

3.      Copy the service file into a virtual directory, and the assembly into the \bin subdirectory of that virtual directory. 

4.      Copy the configuration file into the virtual directory, and name it Web.config. 

The application is then accessible via the URL of the service file in the application root. 

To host a Windows Communication Foundation service within a .NET application, compile the service type into a class library assembly referenced by the application, and program the application to host the service using the Windows Communication Foundation’s System.ServiceModel.ServiceHost class.  Here is an example of the simple programming required: 

string httpBaseAddress = "http://www.woodgrove.com:8000/";

string tcpBaseAddress = "net.tcp://www.woodgrove.com:8080/";

 

Uri httpBaseAddressUri = new Uri(httpBaseAddress);

Uri tcpBaseAddressUri = new Uri(tcpBaseAddress);

 

Uri[] baseAdresses = new Uri[] {

    httpBaseAddressUri,

    tcpBaseAddressUri};

 

using(ServiceHost host = new ServiceHost(

typeof(Service), //”Service” is the name of the service type    baseAdresses))

{

    host.Open();

 

    […] //Wait to receive messages

    host.Close();

}

This example shows how addresses for one or more transport protocols are specified in the construction of a Windows Communication  Foundation System.ServiceModel.ServiceHost.  These addresses are referred to as base addresses. 

The address provided for any endpoint of a Windows Communication Foundation service is an address relative to a base address of the endpoint’s host.  The host can have one base address per communication transport protocol.  The base address of an endpoint is relative to whichever of the base addresses of the host is the base address for the communication transport protocol of the endpoint.  In the sample configuration in Listing Three, above, the System.ServiceModel.BasicHttpBinding selected for the endpoint uses HTTP as the transport protocol, so the address of the endpoint, EchoService, is relative to the host’s HTTP base address.  In the case of the host in the example above, the HTTP base address is http://www.woodgrove.com:8000/.  For a service hosted within IIS or WAS, the base address is the URL of the service’s service file. 

Only services hosted in IIS or WAS, and which are configured with HTTP as the transport protocol exclusively, can be made to use the Windows Communication Foundation’s ASP.NET compatibility mode option.  Turning that option on requires two steps. 

1.      The programmer must add the System.ServiceModel.AspNetCompatbilityRequirements attribute to the service type, specifying that ASP.NET compatibility mode is either allowed or required:

[System.ServiceModel.AspNetCompatibilityRequirements(

        RequirementsMode=AspNetCompatbilityRequirementsMode.Require)]

public class DerivativesCalculatorServiceType: IDerivativesCalculator

2.      The administrator must configure the application to use the ASP.NET compatibility mode:

<configuration>

   <system.serviceModel>

         <services>

               […]

         </services>

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

   </system.serviceModel>

</configuration>

Windows Communication Foundation applications can also be configured to use .asmx as the extension for their service files rather than .svc. 

<system.web>

      <compilation>

            <compilation debug="true">

                  <buildProviders>

                        <remove extension=".asmx"/>

                        <add extension=".asmx"

                              type="System.ServiceModel.ServiceBuildProvider,

                              Systemm.ServiceModel,

                              Version=3.0.0.0,

                              Culture=neutral,

                              PublicKeyToken=b77a5c561934e089" />

                  </buildProviders>

            </compilation>

      </compilation>

</system.web>

That option can save one from having to modify clients that have been configured to use the URLs of .asmx service files when modifying a service to use the Windows Communication Foundation. 

Client Development

Clients for ASP.NET Web services are generated using the command-line tool, wsdl.exe, providing the URL of the .asmx file as input.  The corresponding tool provided by the Windows Communication Foundation is svcutil.exe.  It generates a code module with the definition of the service contract and the definition of a proxy class.  It also generates a configuration file with the address and binding of the service.

In programming a client of a remote service it is generally advisable to program according to an asynchronous pattern.  The code generated by the wsdl.exe tool always provides for both a synchronous and an asynchronous pattern by default.  The code generated by the svcutil.exe tool can provide for either pattern.  It provides for the synchronous pattern by default.  If the tool is executed with the /async switch, then the generated code provides for the asynchronous pattern. 

There is no guarantee that names in the proxy classes generated by ASP.NET’s wsdl.exe tool will, by default, match the names in proxy classes generated by the Windows Communication Foundation’s svcutil.exe tool.  In particular, the names of the properties of classes that have to be serialized using the System.Xml.Serialization.XmlSerializer are, by default, given the suffix Property in the code generated by the svcutil.exe tool, which was not the case with the wsdl.exe tool. 

Message Representation

The headers of the SOAP messages sent and received by ASP.NET Web services can be customized.  A class is derived from System.Web.Services.Protocols to define the structure of the header, and then the System.Web.Services.SoapHeader attribute is used to indicate the presence of the header. 

public class SomeProtocol : SoapHeader

{

    public long CurrentValue;

    public long Total;

}

 

[WebService]

public interface IEcho

{

    SomeProtocol ProtocolHeader

    {

      get;

      set;

    }

 

    [WebMethod]

    [SoapHeader("ProtocolHeader")]

    string PlaceOrders(PurchaseOrderType order);

}

 

public class Service: WebService, IEcho

{

    private SomeProtocol protocolHeader;

   

    public SomeProtocol ProtocolHeader

    {

      get

      {

        return this.protocolHeader;

      }

     

      set

      {

        this.protocolHeader = value;

      }

    }

   

    string PlaceOrders(PurchaseOrderType order)

    {

      long currentValue = this.protocolHeader.CurrentValue;

    }

}

The Windows Communication Foundation provides the attributes, System.ServiceModel.MessageContract, System.ServiceModel.MessageHeader, and System.ServiceModel.MessageBody to describe the structure of the SOAP messages sent and received by a service:

[DataContract]

public class SomeProtocol

{

    [DataMember]

    public long CurrentValue;

    [DataMember]

    public long Total;

}

 

[DataContract]

public class Item

{

    [DataMember]

    public string ItemNumber;

    [DataMember]

    public decimal Quantity;

    [DataMember]

    public decimal UnitPrice;

}

 

[MessageContract]

public class ItemMesage

{

    [MessageHeader]

    public SomeProtocol ProtocolHeader;

    [MessageBody]

    public Item Content;

}

 

[ServiceContract]

public interface IItemService

{

    [OperationContract]

    public void DeliverItem(ItemMessage itemMessage);

}

This syntax yields an explicit representation of the structure of the messages, whereas the structure of messages is merely implied by the code of an ASP.NET Web service.  Also, in the ASP.NET syntax, message headers are represented as properties of the service, such as the ProtocolHeader property in the example above, whereas in the Windows Communication Foundation syntax, they are more accurately represented as properties of messages.  Also, the Windows Communication Foundation allows message headers to be added to the configuration of endpoints: <