[ Home | Syllabus | Course Notes | Assignments | Search]
Internet for computers not people.
Based on existing and emerging standards:
HTTP (HyperText Transport Protocol)
SOAP (Simple Object Access Protocol)
UDDI (Universal Description, Discovery and Integration)
WS-POLICY (Web Services Policy)
Can be implemented using many current Internet pieces (web servers, protocols)
Remember the "calc" example (our first WebForm) - that was for users who wanted to add two numbers and used the web form for data entry.
But what is a program wanted to Add two numbers
It could emulate the form submission by sending in a HTTP request and then parse the HTTP response to get the answer (sometimes called screen scraping)
It could contact a web application oriented to programs NOT people - that is web services - don't need to worry about the appearance of the output - and uses XML to more precisely define the structure of the output - lots of XML technology can be used to ease the programming task
For example
This example adds 2 and 2:
POST /calc.asmx HTTP/1.1 Host: www.wintellect.com Content-Type: text/xml; charset=utf-8 Content-Length: 338 SOAPAction: "http://tempuri.org/Add" <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <Add xmlns="http://tempuri.org/"> <a>2</a> <b>2</b> </Add> </soap:Body> </soap:Envelope>
And here’s how the Web service would respond:
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 353 <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <AddResponse xmlns="http://tempuri.org/"> <AddResult>4</AddResult> </AddResponse> </soap:Body> </soap:Envelope>
//// also supported is the GET method
The Web service responds as follows:
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 80 <?xml version="1.0" encoding="utf-8"?> <int xmlns="http://tempuri.org/">4</int>
//// Or alternatively
POST /calc.asmx/Add HTTP/1.1 Host: www.wintellect.com Content-Type: application/x-www-form-urlencoded Content-Length: 7 a=2&b=2
And here’s the Web service’s response:
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 80 <?xml version="1.0" encoding="utf-8"?> <int xmlns="http://tempuri.org/">4</int>
<%@ WebService Language="C#" Class="CalcService" %> using System; using System.Web.Services; [WebService (Name="Calculator Web Service", Description="Performs simple math over the Web")] class CalcService { [WebMethod (Description="Computes the sum of two integers")] public int Add (int a, int b) { return a + b; } [WebMethod (Description="Computes the difference between two integers")] public int Subtract (int a, int b) { return a - b; } }
Normally a Web Service is accessed by a web service client
For testing can use a browser - why?
the magic of WSDL (Web Service Description Language) and SOAP/HTTP makes this possible
For Example
Suppose web services is available at "http://128.82.4.94:8000/cwild/Book1/Chap11/Calc/Calc.asmx"
Putting this URL in a IE browser would give this window
Notice that it has identified the two web method functions
Clicking on the "Add" method gives
It also knows the parameter names and allows you to put in values for them
I put in values "45" and "3"
Clicking the "invoke" button
Answer is "48"
This XML file is the key to making the above work - here is the WSDL for the above web service (obtained by clicking the "Service Description" above
</types>
<portType name="Calculator_x0020_Web_x0020_ServiceSoap">
- <service name="Calculator_x0020_Web_x0020_Service">
Parameter Name |
Description |
BufferResponse |
Enables and disables response buffering |
CacheDuration |
Caches responses generated by this method for the specified number of seconds |
Description |
Adds a textual description to a Web method |
EnableSession |
Enables and disables session state for this Web method |
MessageName |
Specifies the Web method’s name |
TransactionOption |
Specifies the transactional behavior of a Web method |
[WebMethod (CacheDuration="10")] public string GetCurrentTime () { return DateTime.Now.ToShortTimeString (); }
class CalcService : WebService { [WebMethod (EnableSession="true", Description="Adds an item to a shopping cart")] public void AddToCart (Item item) { ShoppingCart cart = (ShoppingCart) Session["MyShoppingCart"]; cart.Add (item); } }
Possible because relies on XML which can represent almost any complex type
Uses System.Xml.Serialization.XmlSerializer class
XML Schema allows "rehydrating" of the object
Consider the example
<%@ WebService Language="C#" Class="LocatorService" %> using System; using System.Web.Services; using System.Data; using System.Data.SqlClient; [WebService (Name="Bookstore Locator Service", Description="Retrieves bookstore information from the Pubs database")] class LocatorService { [WebMethod (Description="Finds bookstores in a specified state")] public Bookstore[] FindStores (string state) { return FindByState (state); } Bookstore[] FindByState (string state) { SqlDataAdapter adapter = new SqlDataAdapter ("select * from stores where state = \'" + state + "\'", "server=localhost;database=pubs;uid=sa;pwd="); DataSet ds = new DataSet (); adapter.Fill (ds); DataTable table = ds.Tables[0]; Bookstore[] stores = new Bookstore[table.Rows.Count]; for (int i=0; i<table.Rows.Count; i++) { stores[i] = new Bookstore ( table.Rows[i]["stor_name"].ToString ().TrimEnd (new char[] { ' ' }), table.Rows[i]["stor_address"].ToString ().TrimEnd (new char[] { ' ' }),
table.Rows[i]["city"].ToString ().TrimEnd (new char[] { ' ' }), table.Rows[i]["state"].ToString ().TrimEnd (new char[] { ' ' }) ); } return stores; } } public class Bookstore { public string Name; public string Address; public string City; public string State; public Bookstore () {} public Bookstore (string name, string address, string city, string state) { Name = name; Address = address; City = city; State = state; } }
The schema is obtained from the WSDL generated by .NET
<s:complexType name="ArrayOfBookstore"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Bookstore" nillable="true" type="s0:Bookstore" /> </s:sequence> </s:complexType> <s:complexType name="Bookstore"> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="Name" nillable="true" type="s:string" /> <s:element minOccurs="1" maxOccurs="1" name="Address" nillable="true" type="s:string" /> <s:element minOccurs="1" maxOccurs="1" name="City" nillable="true" type="s:string" /> <s:element minOccurs="1" maxOccurs="1" name="State" nillable="true" type="s:string" /> </s:sequence> </s:complexType>
F1: This is the name of the service being accessed
F2: This is a SOAP extension in the HTTP header - HTTP is extensible
F3: asking to invoke the "Add" function
F4: the body of the HTTP request is an XML document
F5: XML namespace
F6: the Add function takes two parameters named "a" and "b"
F7: Return value of the "Add" function
F8: embed parameters in query string
F9: returns an array of BookStore objects - interesting
F10: this is from DB schema
F11: trims off any trailing blanks