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> |
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, 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, 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> |
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>
|
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>
|
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.

