.NET Framework Essentials, 2nd Ed.: Web Services, Part 3by Thuan L. Thai, Hoang Lam
Editor's Note: This is the third of four excerpts from the second edition of O'Reilly's .NET Framework Essentials, 2nd Ed. by Thuan L. Thai and Hoang Lam. The complete series of excerpts covers Web services in the context of the .NET framework. Part one was an overview of .NET Web services. Part two focused on Web service providers. This third part covers Web services consumers.
Web Services Consumers
Now that you have successfully created a Web Service, let's take a look at how this Web Service is used by web clients. Web Services clients communicate with Web Services through standard web protocols. They send and receive XML-encoded messages to and from the Web Services. This means any application on any platform can access the Web Services as long as it uses standard web protocols and understands the XML-encoded messages. As mentioned earlier, there are three protocols that the web clients can employ to communicate with the servers (Web Services): HTTP GET, HTTP POST, and SOAP. We demonstrate next how to build client applications that utilize each of these protocols. These Web Services-client applications are done in both VB6 and .NET languages, such as C# and VB.NET, to demonstrate the cross-language/cross-platform benefits of Web Services. For example, you can replace the example in VB6 with Perl running on Unix, and the Web Services should still be serving.
HTTP GET Consumer
Let's look at how it is done using HTTP GET first, since it is the simplest. In the examples that follow, we use localhost as the name of the web server running the service and PubsWS as the virtual directory. If you have deployed the sample Web Service on a remote server, you'll need to substitute the name of the server and virtual directory as appropriate.
If you point your web browser at the Web Service URL (http://localhost/ PubsWS/PubsWS.asmx), it will give you a list of supported methods. To find out more about these methods, click one of them. This brings up a default Web Service consumer. This consumer, autogenerated through the use of reflection, is great for testing your Web Services' methods. It uses the HTTP GET protocol to communicate with the Web Service. This consumer features a form that lets you test the method (see Figure 6-3), as well as descriptions of how to access the method via SOAP, HTTP GET, or HTTP POST.
Here is the description of the GET request and response supplied by the default consumer:
The following is a sample HTTP GET request and response. The placeholders shown need to be replaced with actual values. GET /PubsWS/PubsWS.asmx/GetAuthor?sSSN=string HTTP/1.1 Host: localhost HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: length <?xml version="1.0" encoding="utf-8"?> <DataSet xmlns="http://Oreilly/DotNetEssentials/"> <schema xmlns="http://www.w3.org/2001/XMLSchema">schema</schema>xml </DataSet>
Using HTTP GET protocol, the complete URL to invoke the web method, along with parameters, can be the following:
Here is the response, including HTTP response headers and the raw XML (note how the response includes the serialized schema and data from the DataSet object):
Cache-Control: private, max-age=0 Date: Tue, 08 May 2001 20:53:16 GMT Server: Microsoft-IIS/5.0 Content-Length: 2450 Content-Type: text/xml; charset=utf-8 Client-Date: Tue, 08 May 2001 20:53:16 GMT Client-Peer: 127.0.0.1:80 <?xml version="1.0" encoding="utf-8"?> <DataSet xmlns="http://Oreilly/DotNetEssentials/"> <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="NewDataSet" msdata:IsDataSet="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="SelectedAuthor"> <xs:complexType> <xs:sequence> <xs:element name="au_id" type="xs:string" minOccurs="0" /> <xs:element name="au_lname" type="xs:string" minOccurs="0" /> <xs:element name="au_fname" type="xs:string" minOccurs="0" /> <xs:element name="phone" type="xs:string" minOccurs="0" /> <xs:element name="address" type="xs:string" minOccurs="0" /> <xs:element name="city" type="xs:string" minOccurs="0" /> <xs:element name="state" type="xs:string" minOccurs="0" /> <xs:element name="zip" type="xs:string" minOccurs="0" /> <xs:element name="contract" type="xs:boolean" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> <NewDataSet xmlns=""> <SelectedAuthor diffgr:id="SelectedAuthor1" msdata:rowOrder="0"> <au_id>172-32-1176</au_id> <au_lname>White</au_lname> <au_fname>Johnson</au_fname> <phone>408 496-7223</phone> <address>10932 Bigge Rd.</address> <city>Menlo Park</city> <state>CA</state> <zip>94025</zip> <contract>true</contract> </SelectedAuthor> </NewDataSet> </diffgr:diffgram> </DataSet>