What is the difference between ASMX, WCF, and ASP.NET Web API?

13 minute read

Application architecture has evolved from monolithic architecture to SOA architecture in order to make better separation, then to more refined microservice architecture today.

Applications need to communicate among themselves, and to achieve this purpose, Microsoft has developed technologies like ASMX, WCF, and ASP.NET Web API.

Let’s explore them together today.


ASMX


ASMX (ASP.NET Web Services) is the primary web service technology in .NET 1.0 and .NET 2.0.

ASMX provides the ability to build web services that send SOAP (Simple Object Access Protocol) messages over HTTP protocol.

SOAP message

SOAP message is in XML format.

SOAP message request sample:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
    <soapenv:Header />
    <soapenv:Body>
        <tem:GetFullName>
            <!--Optional:-->
            <tem:firstName>jiangong</tem:firstName>
            <!--Optional:-->
            <tem:lastName>sun</tem:lastName>
        </tem:GetFullName>
    </soapenv:Body>
</soapenv:Envelope>

ASMX web service code sample

using System.Web.Services;
namespace AsmxWebService
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class NameService : System.Web.Services.WebService
    {
        [WebMethod]
        public string GetFullName(string firstName, string lastName)
        {
            return $"{firstName} {lastName}";
        }
    }
}


WSDL

WSDL (Web Service Description Language) is a language to describe the service.


WSDL structure

WSDL Section Description
types Defines the (XML Schema) data types used by the web service
message Defines the data elements for each operation
portType Describes the operations that can be performed and the messages involved
binding Defines the protocol and data format for each port type


PrintService’s WSDL detail

PrintService’s WSDL code

<wsdl:definitions targetNamespace="http://tempuri.org/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
   <wsdl:types>
      <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
         <s:element name="GetFullName">
            <s:complexType>
               <s:sequence>
                  <s:element minOccurs="0" maxOccurs="1" name="firstName" type="s:string"/>
                  <s:element minOccurs="0" maxOccurs="1" name="lastName" type="s:string"/>
               </s:sequence>
            </s:complexType>
         </s:element>
         <s:element name="GetFullNameResponse">
            <s:complexType>
               <s:sequence>
                  <s:element minOccurs="0" maxOccurs="1" name="GetFullNameResult" type="s:string"/>
               </s:sequence>
            </s:complexType>
         </s:element>
      </s:schema>
   </wsdl:types>
   <wsdl:message name="GetFullNameSoapIn">
      <wsdl:part name="parameters" element="tns:GetFullName"/>
   </wsdl:message>
   <wsdl:message name="GetFullNameSoapOut">
      <wsdl:part name="parameters" element="tns:GetFullNameResponse"/>
   </wsdl:message>
   <wsdl:portType name="NameServiceSoap">
      <wsdl:operation name="GetFullName">
         <wsdl:input message="tns:GetFullNameSoapIn"/>
         <wsdl:output message="tns:GetFullNameSoapOut"/>
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="NameServiceSoap" type="tns:NameServiceSoap">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="GetFullName">
         <soap:operation soapAction="http://tempuri.org/GetFullName" style="document"/>
         <wsdl:input>
            <soap:body use="literal"/>
         </wsdl:input>
         <wsdl:output>
            <soap:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:binding name="NameServiceSoap12" type="tns:NameServiceSoap">
      <soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="GetFullName">
         <soap12:operation soapAction="http://tempuri.org/GetFullName" style="document"/>
         <wsdl:input>
            <soap12:body use="literal"/>
         </wsdl:input>
         <wsdl:output>
            <soap12:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="NameService">
      <wsdl:port name="NameServiceSoap" binding="tns:NameServiceSoap">
         <soap:address location="http://localhost:61331/PrintService.asmx"/>
      </wsdl:port>
      <wsdl:port name="NameServiceSoap12" binding="tns:NameServiceSoap12">
         <soap12:address location="http://localhost:61331/PrintService.asmx"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>

See more information about WSDL: W3C WSDL Specification


SOAP vs WSDL vs UDDI


ASMX service consumption

To consume the ASMX service, you can use any web browser or SoapUI.

Consume ASMX service in Web browser

Call:

Result:

Consume ASMX service in SoapUI

To consume the WCF service in SoapUI, you must enter a .WSDL suffix after .asmx.

Call and result:


ASMX project source project

Download SOAP ASMX service sample project



WCF


WCF (Windows Communication Foundation) is a framework for building service-oriented applications. WCF is introduced since .NET 3.0.

WCF Architecture

Source: Microsoft


WCF communication binding

Source: Microsoft


SOAP WCF service sample code

WCF can transfer SOAP messages over HTTP protocol by default, just like ASMX service.

SOAP WCF service sample code.

[ServiceContract]
public interface IPrintService
{
    [OperationContract]
    Name GetFullName(string firstName, string lastName);
}

public class PrintService : IPrintService
{
    public Name GetFullName(string firstName, string lastName)
    {
        return new Name
        {
            FirstName = firstName,
            LastName = lastName
        };
    }
}


SOAP WCF WSDL

SOAP WCF WSDL


SOAP WCF WSDL detail


SOAP WCF WSDL code

<wsdl:definitions name="PrintService" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">
   <wsdl:types>
      <xsd:schema targetNamespace="http://tempuri.org/Imports">
         <xsd:import schemaLocation="http://localhost:61543/PrintService.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
         <xsd:import schemaLocation="http://localhost:61543/PrintService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
         <xsd:import schemaLocation="http://localhost:61543/PrintService.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/WcfSoapWebService"/>
      </xsd:schema>
   </wsdl:types>
   <wsdl:message name="IPrintService_GetFullName_InputMessage">
      <wsdl:part name="parameters" element="tns:GetFullName"/>
   </wsdl:message>
   <wsdl:message name="IPrintService_GetFullName_OutputMessage">
      <wsdl:part name="parameters" element="tns:GetFullNameResponse"/>
   </wsdl:message>
   <wsdl:portType name="IPrintService">
      <wsdl:operation name="GetFullName">
         <wsdl:input wsaw:Action="http://tempuri.org/IPrintService/GetFullName" message="tns:IPrintService_GetFullName_InputMessage"/>
         <wsdl:output wsaw:Action="http://tempuri.org/IPrintService/GetFullNameResponse" message="tns:IPrintService_GetFullName_OutputMessage"/>
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="BasicHttpBinding_IPrintService" type="tns:IPrintService">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="GetFullName">
         <soap:operation soapAction="http://tempuri.org/IPrintService/GetFullName" style="document"/>
         <wsdl:input>
            <soap:body use="literal"/>
         </wsdl:input>
         <wsdl:output>
            <soap:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="PrintService">
      <wsdl:port name="BasicHttpBinding_IPrintService" binding="tns:BasicHttpBinding_IPrintService">
         <soap:address location="http://localhost:61543/PrintService.svc"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>


SOAP WCF service consumption

Add WSDL in SoapUI:

PrintService.svc’s .svc means Service.

SOAP WCF service consumption:


WCF service bindings

In addition, WCF provides much more features to build secure, complex WCF services. WCF can work with other protocols like TCP, HTTPS, and UDP.


Here are all the WCF Bindings:

Binding type Note Description
BasicHttpBinding it’s the most used binding A binding that is suitable for communicating with WS-Basic Profile conformant Web services, for example, ASP.NET Web services (ASMX)-based services. This binding uses HTTP as the transport and text/XML as the default message encoding.
WSHttpBinding secure HTTPS binding A secure and interoperable binding that is suitable for non-duplex service contracts.
WS2007HttpBinding   A secure and interoperable binding that provides support for the correct versions of the Security, ReliableSession, and TransactionFlow binding elements.
WSDualHttpBinding   A secure and interoperable binding that is suitable for duplex service contracts or communication through SOAP intermediaries.
WSFederationHttpBinding   A secure and interoperable binding that supports the WS-Federation protocol, enabling organizations that are in a federation to efficiently authenticate and authorize users.
WS2007FederationHttpBinding    
NetTcpBinding it uses TCP protocol to transfer messages, and faster than WSHttpBinding A secure and optimized binding suitable for cross-machine communication between WCF applications.
NetNamedPipeBinding   A secure, reliable, optimized binding that is suitable for on-machine communication between WCF applications.
NetMsmqBinding it can work with MSMQ (Message Queuing) A queued binding that is suitable for cross-machine communication between WCF applications.
NetPeerTcpBinding   A binding that enables secure, multi-machine communication.
WebHttpBinding RESTful service, passing HTTP message instead of SOAP message over HTTP protocol A binding used to configure endpoints for WCF Web services that are exposed through HTTP requests instead of SOAP messages.
MsmqIntegrationBinding   A binding that is suitable for cross-machine communication between a WCF application and existing Message Queuing (also known as MSMQ) applications.
NetHttpBinding WebSocket communication, introduced in .NET 4.5 NetHttpBinding is a binding designed for consuming HTTP or WebSocket services and uses binary encoding by default.
NetHttpsBinding WebSocket communication, introduced in .NET 4.5 NetHttpsBinding is a secure binding designed for consuming HTTP or WebSocket services and uses binary encoding by default.
BasicHttpContextBinding Derives from BasicHttpBinding A binding suitable for communicating with WS-Basic Profile conformant Web services that enables HTTP cookies to be used to exchange context.
NetTcpContextBinding Derives from NetTcpBinding A secure and optimized binding suitable for cross-machine communication between WCF applications that enables SOAP headers to be used to exchange context.
WSHttpContextBinding Derives from WsHttpBinding A secure and interoperable binding suitable for non-duplex service contracts that enables SOAP headers to be used to exchange context.
UdpBinding UDP A binding to use when sending a burst of simple messages to a large number of clients simultaneously.


REST WCF service sample code

WCF also can act as RESTful service with WebHttpBinding.

REST WCF service sample:

[ServiceContract]
public interface IRestPrintService
{
    [OperationContract]
    [WebGet(UriTemplate = "/GetFullName", ResponseFormat = WebMessageFormat.Json)]
    string GetFullName();

    [OperationContract]
    [WebInvoke(UriTemplate = "/PostName/{firstName}/{lastName}", Method = "POST")]
    string PostNameInfo(string firstName, string lastName);
}

public class RestPrintService : IRestPrintService
{
    public string GetFullName()
    {
        return "{'name':'SUN Jiangong'}";
    }

    public string PostNameInfo(string firstName, string lastName)
    {
        var name = new Name
        {
            FirstName = firstName,
            LastName = lastName
        };

        return JsonConvert.SerializeObject(name);
    }
}


REST WCF WADL

WADL (Web Application Description Language) is a machine-readable XML description of HTTP-based web services.


REST WCF WADL structure


REST WCF WADL code

<application xmlns="http://wadl.dev.java.net/2009/02">
   <doc xml:lang="en" title="http://localhost:61686"/>
   <resources base="http://localhost:61686">
      <resource path="RestPrintService.svc/PostName" id="PrintService.svc">
         <doc xml:lang="en" title="PrintService.svc"/>
         <method name="POST" id="PrintService.svc 1">
            <doc xml:lang="en" title="PrintService.svc 1"/>
            <request>
               <representation mediaType="application/json"/>
            </request>
            <response status="">
               <representation mediaType="application/json"/>
            </response>
            <response status="404">
               <representation mediaType="text/html; charset=UTF-8" element="html"/>
            </response>
            <response status="400">
               <representation mediaType="text/html" element="html"/>
            </response>
            <response status="200">
               <representation mediaType="application/xml; charset=utf-8" element="ser:string" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/"/>
            </response>
            <response status="0">
               <representation mediaType="" element="data"/>
            </response>
         </method>
      </resource>
   </resources>
</application>


REST WCF service consumption


SOAP and REST WCF services source projects

Download SOAP and REST WCF service sample project


ASP.NET Web API

ASP.NET Web API pass messages over HTTP or HTTPS protocol.

Modern ASP.NET Web APIs are RESTful.

REST

REST (RepreSentational State Transfer)

REST Web API has the following characteristics:

  • Client-server architecture

The principle behind the client-server constraints is the separation of concerns.

  • Statelessness

The client-server communication is constrained by no client context being stored on the server between requests. Each request from any client contains all the information necessary to service the request, and the session state is held in the client. The session state can be transferred by the server to another service such as a database to maintain a persistent state for a period and allow authentication.

  • Cacheability

Well-managed caching partially or completely eliminates some client-server interactions, further improving scalability and performance.

  • Layered system

  • Code on demand (optional)

Servers can temporarily extend or customize the functionality of a client by transferring executable code

  • Uniform interface

The uniform interface constraint is fundamental to the design of any RESTful system.

The four constraints for this uniform interface are:

  • Resource identification in requests
  • Resource manipulation through representations
  • Self-descriptive messages
  • Hypermedia as the engine of application state (HATEOAS)


Web API sample code

[HttpGet]
[Route("api/v1/Values/{id}")]
public HttpResponseMessage Get(int id)
{
    var content = "{ 'id';" + id + "}";
    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, "value");
    response.Content = new StringContent(content, Encoding.UTF8);
    return response;
}


Web API consumption


Web API source project

Download ASP.NET Web API sample project

SUN Jiangong

SUN Jiangong

A senior .NET engineer, software craftsman. Passionate about new technologies.