Before you begin developing your web service, you need to decide how you’re going host it. You have several choices: ASP.NET and .NET Remoting are the easiest ones to choose, and I’ll be focusing on ASP.NET in these examples, because it’s the option that gives you the most flexibility.
If you choose to serve your web services with ASP.NET, you need to be sure you have a web server capable of serving ASP.NET pages. IIS, the web server that ships with all Windows NT and Windows Server installations, will do just fine. However, if you’re running on Windows XP personal workstation, you don’t have a web server.Describing Web Services
A web service is described with a WSDL file. The following elements are involved in a WSDL document:
definitions
types
This optional element can be used to define the data types which are used to describe the messages exchanged by this service.
message
This
element is used to describe the messages exchanged by this service.
The message
element may have any number of
part
sub-elements, each of which can represent an
individual parameter to the message. In general, there will be two
message
elements for each combination of method
and transport; one for the request and one for the response.
portType
This element is used to define a set of
abstract operations. An abstract operation represents a single
round-trip query and response, and gives it a name which will be used
in the binding
element. In general, there will be
one portType
element for each
transport
.
binding
This element is used to connect an
abstract operation to its message and transport. Transports can
include SOAP, HTTP GET, and HTTP POST. In general, there will be one
binding
element for each
transport
.
service
This element is used to map each
portType
to its binding
,
including a URL used to access the service.
documentation
This element is used to contain
additional, human-readable information about the service. It may
appear anywhere in the WSDL document, has a mixed content model, and
may contain any number of any other element (xs:any
in XML Schema).
import
This element is used to allow a WSDL document to include the contents of another.
Now I’ll build a relatively simple WSDL document, which describes an inventory query service which I’ll introduce a little later. The XML prolog and document element are fairly uneventful, except for the large number of namespaces. The namespaces will be used for various purposes later in the document:
<?xml version="1.0" encoding="utf-8"?> <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://angushardware.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://angushardware.com" xmlns="http://schemas.xmlsoap.org/wsdl/">
The
types element defines three elements using XML Schema:
GetNumberInStock
,
GetNumberInStockResponse
, and
int
. These elements will all be scoped in the
target namespace, http://angushardware.com
. The
first two are complex types which define the parameters and return
values of the messages, and the last one is equivalent to the
predefined xs:int
type:
<types> <s:schema elementFormDefault="qualified" targetNamespace="http://angushardware.com"> <s:element name="GetNumberInStock"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="productCode" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="GetNumberInStockResponse"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="GetNumberInStockResult" type="s:int" /> </s:sequence> </s:complexType> </s:element> <s:element name="int" type="s:int" /> </s:schema> </types>
The two messages are defined here.
GetNumberInStockSoapIn
is a SOAP version of the
GetNumberinStock
request message, and
GetNumberInStockSoapOut
is a SOAP version of the
GetNumberInStockResponse
response message:
<message name="GetNumberInStockSoapIn"> <part name="parameters" element="s0:GetNumberInStock" /> </message> <message name="GetNumberInStockSoapOut"> <part name="parameters" element="s0:GetNumberInStockResponse" /> </message>
This
web service only supports a single operation,
GetNumberInStock
, so there is only one
portType
element. This element maps the
GetNumberInStock
operation to its SOAP input and
output messages:
<portType name="InventoryQuerySoap"> <operation name="GetNumberInStock"> <input message="s0:GetNumberInStockSoapIn" /> <output message="s0:GetNumberInStockSoapOut" /> </operation> </portType>
The
binding
element associates the
InventoryQuerySoap portType
with the SOAP
transport, and defines the GetNumberInStock
operation as a SOAP message:
<binding name="InventoryQuerySoap" type="s0:InventoryQuerySoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="GetNumberInStock"> <soap:operation soapAction="http://angushardware.com/GetNumberInStock" style="document" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding>
The
service element describes the InventoryQuery
service as being located at the URL http://127.0.0.1/dotNetAndXml/InventoryQuery.asmx
,
using the InventoryQuerySoap
binding:
<service name="InventoryQuery"> <port name="InventoryQuerySoap" binding="s0:InventoryQuerySoap"> <soap:address location="http://127.0.0.1/dotNetAndXml/InventoryQuery.asmx" /> </port> </service>
Finally, as in all XML documents, the root element has to be closed:
</definitions>
That’s it, the InventoryQuery
web
service is now fully described.
Example 10-1 shows the complete WSDL document I built. It’s not a very complicated schema, but its contents can be confusing. Don’t worry, though; you’ll very rarely have to create it by hand. You’ll see in a moment how the .NET Framework creates one for you on demand.
<?xml version="1.0" encoding="utf-8"?> <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://angushardware.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://angushardware.com" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://angushardware.com"> <s:element name="GetNumberInStock"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="productCode" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="GetNumberInStockResponse"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="GetNumberInStockResult" type="s:int" /> </s:sequence> </s:complexType> </s:element> <s:element name="int" type="s:int" /> </s:schema> </types> <message name="GetNumberInStockSoapIn"> <part name="parameters" element="s0:GetNumberInStock" /> </message> <message name="GetNumberInStockSoapOut"> <part name="parameters" element="s0:GetNumberInStockResponse" /> </message> <portType name="InventoryQuerySoap"> <operation name="GetNumberInStock"> <input message="s0:GetNumberInStockSoapIn" /> <output message="s0:GetNumberInStockSoapOut" /> </operation> </portType> <binding name="InventoryQuerySoap" type="s0:InventoryQuerySoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <operation name="GetNumberInStock"> <soap:operation soapAction="http://angushardware.com/GetNumberInStock" style="document" /> <input> <soap:body use="literal" /> </input> <output> <soap:body use="literal" /> </output> </operation> </binding> <service name="InventoryQuery"> <port name="InventoryQuerySoap" binding="s0:InventoryQuerySoap"> <soap:address location="http://127.0.0.1/dotNetAndXml/InventoryQuery.asmx" /> </port> </service> </definitions>
3.143.247.125