Master C# Logo banner
Welcome to MasterCSharp.com - Master C#, the easy way... - by Saurabh Nandu

 


Proverb Web Service - Understanding the Web Service WSDL - Part 4

Add Comment
 

 
SDK
Beta2

Introduction
In the previous few articles in the Proverb Web Service series I have shown you how to create the Proverb Web Service, as well as I showed you how to create a few clients that consume the Proverb web service. While creating these clients I took it for granted that the service was created by me and I knew the details of how the web service was implemented i.e. I knew the exact methods to call, the method parameters, the data-type of these parameters as well as the return value data-type.
In case I did not know how the web service was implemented and I did not have tools like WSDL.EXE that auto-generate proxy classes, then it might be a tuff task to consume this web service.
In this article I have a look in to WSDL (web service Discovery Language) of the Proverb web service, and try to make sense out of it :) !!

WSDL
WSDL (web service Discovery Language) is again a web standard maintained by W3C ( www.w3.org/TR/wsdl ), currently in version 1.1. Similar to everything else related with web services, even WSDL is XML formatted (you guessed this one, right??). WSDL files are used to describe the methods exposed by the web service, the protocols you can use to call those methods, the method parameters, the data-type of the parameters and the return value's data-type. In short WSDL contains all the metadata that you might need in order to create clients for consuming the web service. Even though WSDL is a very complex and evolving standard, .NET developers have no trouble implementing, since the .NET Platform generates the WSDL for each web service automatically !! (You can add this in your '101 reasons to adopt the .NET Platform' list :) !). Many other platforms require you to manually code the WSDL file for your web services!

To access the WSDL of any web service created on the .NET Platform just append the ?WSDL argument after the web service URL in any browser and you will be presented with the auto-generated WSDL file for the web service. For example if you installed the Proverb Web Service with the path http://localhost/ProverbService/ProverbService.asmx  append the ?WSDL argument to this path in your browser to view the WSDL document for the web service i.e. call the new URL http://localhost/ProverbService/ProverbService.asmx?WSDL . In case you don't have the Proverb web service installed on you computer, click here to view the WSDL of the Proverb Web Service hosted on my server. I will keep referring to it again throughout the article so better keep the WSDL file open and have a good look at it!

WSDL Sections
The WSDL of any web service is an XML file that will containing at several elements nested within the root element called definitions. The table below summarizes the use of some common important elements present in all WSDL files..

Element Description
types This element defines the schema of the data-types used in the web service. Both input parameters and return values of each method are defined in this section using any of the existing XML data-type description standards like XSD, XML Schema etc.
messages This element defines the input and out parameters for each of the methods the web service exposes. This section refers to the data-types  defined in the above types section.
operation This element defines the operations your web services supports.
portType This element ties the different access methods with the messages elements defined above.
binding This element defines the complete protocols that can be used to access the Web Method (Http POST, Http GET, SOAP) and encoding to be used for each of these protocols.
port This elements contains the URL for accessing the web service.
service This element is a collection of the port elements.

Analyzing the Proverb web service WSDL
I guess you already have the WSDL of the Proverb Service on your desktop, let's understand what information the different sections of this file gives us.

1) definitions (root element)

 
<?xml version="1.0" encoding="utf-8" ?>
<definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s0="http://www.mastercsharp.com/WebService" targetNamespace="http://www.mastercsharp.com/WebService" xmlns="http://schemas.xmlsoap.org/wsdl/">

</definitions>
Listing 1: definition element

You can see from the above listing 1, that the definitions element is the root element and it defines a lot of XML namespaces that are used in the XML formatted WSDL document.
Observe that since I had defined the the Namespace property of the WebServiceAttribute applied to the Proverbs class as http://www.mastercsharp.com/WebService, the WSDL for this service defines a XML Namespace with the same URL where all the custom web service related data-types will be placed under i.e. xmlns:s0="http://www.mastercsharp.com/WebService".

2) types element

<types>
 <s:schema attributeFormDefault="qualified"
	elementFormDefault="qualified"
	targetNamespace="http://www.mastercsharp.com/WebService">

  <s:element name="GetProverb">
   <s:complexType />
  </s:element>

  <s:element name="GetProverbResponse">
   <s:complexType>
    <s:sequence>
     <s:element minOccurs="1"
	maxOccurs="1" name="GetProverbResult" nillable="true" type="s:string" />
    </s:sequence>
   </s:complexType>
  </s:element>

  <s:element name="AddProverb">
   <s:complexType>
    <s:sequence>
     <s:element minOccurs="1"
	maxOccurs="1" name="userProverb" nillable="true" type="s:string" />
    </s:sequence>
   </s:complexType>
  </s:element>

  <s:element name="AddProverbResponse">
   <s:complexType>
     <s:sequence>
      <s:element minOccurs="1"
	maxOccurs="1" name="AddProverbResult" nillable="true" type="s:string" />
     </s:sequence>
   </s:complexType>
  </s:element>

  <s:element name="string" nillable="true" type="s:string" />

 </s:schema>
</types>
Listing 2: types element

Listing 2, displays the types element for the Proverb Web Service WSDL, the types element defines the XML schema for the parameters used during method calls. WSDL treats the input parameters and return values of a method call as separate entities.  The input parameters are named with the same name as the method name. Hence in the above snip, the element with name attribute as GetProverb represents the input parameter for the method GetProverb, but since this method takes no parameters this element has an empty complexType element. Similarly, the element with name attribute as AddProverb represents the input parameter from the method AddProverb. Also this method takes a string userProverb as the input parameter hence even the WSDL AddProverb element defines a child element of type string. The minOccurs and maxOccurs attributes indicate that this element is needed and it can occur only a single time.

The return parameters of the methods are marked with the method name followed by the word Response so the elements named GetProverbResponse and AddProverbResponse define the schema for the return values for the methods GetProverb and AddProverb respectively. Both these methods return a string type. Lastly, the schema from the string type is defined.

3) message element

<message name="GetProverbSoapIn">
  <part name="parameters" element="s0:GetProverb" />
</message>
<message name="GetProverbSoapOut">
  <part name="parameters" element="s0:GetProverbResponse" />
</message>
<message name="AddProverbSoapIn">
  <part name="parameters" element="s0:AddProverb" />
</message>
<message name="AddProverbSoapOut">
  <part name="parameters" element="s0:AddProverbResponse" />
</message>
<message name="GetProverbHttpGetIn" />
<message name="GetProverbHttpGetOut">
  <part name="Body" element="s0:string" />
</message>
<message name="AddProverbHttpGetIn">
  <part name="userProverb" type="s:string" />
</message>
<message name="AddProverbHttpGetOut">
  <part name="Body" element="s0:string" />
</message>
<message name="GetProverbHttpPostIn" />
<message name="GetProverbHttpPostOut">
  <part name="Body" element="s0:string" />
</message>
<message name="AddProverbHttpPostIn">
  <part name="userProverb" type="s:string" />
</message>
<message name="AddProverbHttpPostOut">
  <part name="Body" element="s0:string" />
</message>
Listing 3: message element

Listing 3, above defines the WSDL message element. You will observe from the above listing that the message element defines the protocols that can be used to interact with the Web Methods. The method call parameters are post-fixed with In while the return values is post-fixed with Out.  The part child element defines the schema to be used while calling these methods, these schema elements have already defined in the types element (listing 2). The name attribute of the part element defines the name of the parameter if any. For example under the message element with name attribute as AddProverbHttpGetIn the name attribute of the part element is userProverb so if you want to call this web method using HTTP GET request you need to pass along a userProverb parameter so a sample HTTP GET request might be
http://localhost/ProverbService/ProverbService.asmx/AddProverb?userProverb=sample%20proverb

Another observation is that, for each of the web methods defined in the Proverb Web Service, the WSDL has 4 message elements defined. This might not be true for all web services. There are three protocols for calling Web Methods; HTTP GET / HTTP POST and SOAP. Web Methods that deal with complex data-types like DataSet's cannot be called over HTTP GET / HTTP POST since these these data-types cannot be expressed correctly. The .NET runtime automatically senses this can generates only the supported message elements.

4) portType element

<portType name="ProverbsSoap">
  <operation name="GetProverb">
    <input message="s0:GetProverbSoapIn" />
    <output message="s0:GetProverbSoapOut" />
  </operation>
  <operation name="AddProverb">
    <input message="s0:AddProverbSoapIn" />
    <output message="s0:AddProverbSoapOut" />
  </operation>
</portType>
<portType name="ProverbsHttpGet">
  <operation name="GetProverb">
    <input message="s0:GetProverbHttpGetIn" />
    <output message="s0:GetProverbHttpGetOut" />
  </operation>
  <operation name="AddProverb">
    <input message="s0:AddProverbHttpGetIn" />
    <output message="s0:AddProverbHttpGetOut" />
  </operation>
</portType>
<portType name="ProverbsHttpPost">
  <operation name="GetProverb">
    <input message="s0:GetProverbHttpPostIn" />
    <output message="s0:GetProverbHttpPostOut" />
  </operation>
  <operation name="AddProverb">
    <input message="s0:AddProverbHttpPostIn" />
    <output message="s0:AddProverbHttpPostOut" />
  </operation>
</portType>
Listing 4: portType element

The portType element shown in listing 4, is used to bind supported protocols with the message element defined in listing 3. The name attribute of the portType element defines the supported protocols, while the name attribute of the child operation element contains the actual name of the Web Methods. The input and output sub-elements bind the message element required during the method call and method return respectively. The message attribute of the input and output elements directly corresponds with the message element defined in listing 3.

5) binding element

<binding name="ProverbsSoap" type="s0:ProverbsSoap">
  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
  <operation name="GetProverb">
    <soap:operation soapAction="http://www.mastercsharp.com/WebService/GetProverb"
     style="document" />
    <input>
      <soap:body use="literal" />
    </input>
    <output>
      <soap:body use="literal" />
    </output>
  </operation>
  <operation name="AddProverb">
    <soap:operation soapAction="http://www.mastercsharp.com/WebService/AddProverb"
     style="document" />
    <input>
      <soap:body use="literal" />
    </input>
    <output>
      <soap:body use="literal" />
    </output>
  </operation>
</binding>
<binding name="ProverbsHttpGet" type="s0:ProverbsHttpGet">
  <http:binding verb="GET" />
  <operation name="GetProverb">
    <http:operation location="/GetProverb" />
    <input>
      <http:urlEncoded />
    </input>
    <output>
      <mime:mimeXml part="Body" />
    </output>
  </operation>
  <operation name="AddProverb">
    <http:operation location="/AddProverb" />
    <input>
      <http:urlEncoded />
    </input>
    <output>
      <mime:mimeXml part="Body" />
    </output>
  </operation>
</binding>
<binding name="ProverbsHttpPost" type="s0:ProverbsHttpPost">
  <http:binding verb="POST" />
  <operation name="GetProverb">
    <http:operation location="/GetProverb" />
    <input>
      <mime:content type="application/x-www-form-urlencoded" />
    </input>
    <output>
      <mime:mimeXml part="Body" />
    </output>
  </operation>
  <operation name="AddProverb">
    <http:operation location="/AddProverb" />
    <input>
      <mime:content type="application/x-www-form-urlencoded" />
    </input>
    <output>
      <mime:mimeXml part="Body" />
    </output>
  </operation>
</binding>
Listing 5: binding element

The binding element defines the protocols supported by the Web Methods and their encoding-format. The name attribute of the binding element defines the protocol while the type attribute connects to the respective portType element defined in listing 4. Rest of the elements are specific to the protocol being defined and the encoding format required for interacting with the specified protocol.

6) service element

<service name="Proverbs">
  <port name="ProverbsSoap" binding="s0:ProverbsSoap">
    <soap:address location="http://localhost/ProverbService/proverbservice.asmx" />
  </port>
  <port name="ProverbsHttpGet" binding="s0:ProverbsHttpGet">
    <http:address location="http://localhost/ProverbService/proverbservice.asmx" />
  </port>
  <port name="ProverbsHttpPost" binding="s0:ProverbsHttpPost">
    <http:address location="http://localhost/ProverbService/proverbservice.asmx" />
  </port>
</service>
Listing 6: service element

The service element in listing 6 defines the URL to access the Web Methods for the different protocols supported by the web service. The binding attribute of the child port element corresponds to the binding element defined in listing 6. This completes our analysis of the Proverb Web Service WSDL.

Putting it all Together
Honestly, how much of the above made sense ?? (Don't tell me it was a absolute bumper!)
Anyway, just to make things more clear lets take a small example.
Let's say we are presented with the WSDL of this Proverb Web Service and we are supposed call the GetProverb of the web service using HTTP GET to retrieve proverbs. Below is the list of steps in serial order that should be followed to understand how to communicate with the web service.

1) The first step would be to examine the service element from listing 6 and note down that in order to to communicate with the web service we should communicate with the URL.
i.e. http://localhost/ProverbService/proverbservice.asmx,  also note the the binding element i.e. ProverbsHttpGet.

2) Now jump to binding element as in listing 5 and search of the binding element with the name attribute as ProverbsHttpGet. The first thing you should check here is that there exists a operation child element with the name attribute same as the Web Method name you intend to call i.e. GetProverb in this case. This is because if the Web Method does not support being called over HTTP GET then there will be no entry for the respective operation element. Since in this case the element exists, on examining its child elements we find that for calling the GetProverb method we need to append an additional location of /GetProverb after the web service URL. So the complete URL to calling the Web Method over HTTP GET becomes
http://localhost/ProverbService/proverbservice.asmx/GetProverb.
We also observe that the input parameters have to be URL Encoded and the return value is of the MIME type mimeXML and is returned as the body of the HTTP response.

3) Switch to the portType element as in listing 4 and search for the portType element with the name attribute as ProverbsHttpGet. Here note down the message attribute for the input and output elements i.e. GetProverbHttpGetIn and GetProverbHttpGetOut respectively.

4) Move up to the message element and search for message elements with the name attribute as GetProverbHttpGetIn and GetProverbHttpGetOut. We find that the message element with the name attribute GetProverbhttpGetIn has no child elements, this signifies that the GetProverb method has no method call parameters. While the message element with the name attribute GetProverbHttpGetOut has one child element called part with element attribute as string signifying that the GetProverb method returns one return value of the data-type string.

5) Lastly, you can see the schema for the input and output web method parameters from the types element as shown in listing 2.
Equipped with this knowledge, calling the Web Method should be very easy! 

Conclusion
In this article I touched upon the various elements that are contained within the WSDL of a web service. You should have also learned to interpret and understand the composition of the WSDL and its importance in describing a web service.

Comments

Add Comment