Sunday, June 20, 2010

Consuming Web Services

This is a continuation from the post on Web Services. To read the first part, click here.

In the last post, I introduced Web Services to you. We created a service named ForexService that has one operation that accepts two input currencies as strings and returns the exchange rate as double.

To consume the web service, let’s create a separate application (note that it can be any type of application, windows or web). This application will act as a client. Here you need to add a web reference (right click on the project in solution explorer and say add web reference) in your client application for the service (in our case, I can use the HTTP URL http://localhost/Forex/ForexService.asmx because I created the web service on HTTP). You can experiment on different ways to add web reference.

When you add a web reference, a .discomap file is added to your solution. I named the reference to service as Forex and my file looks like:

What is important to notice in this file is the two DiscoveryClientResult details:
  • System.Web.Services.Discovery.ContractReference 
  • System.Web.Services.Discovery.DiscoveryDocumentReference
The ContractReference url is http://localhost/Forex/Service.asmx?wsdl. This is the URL of the contract that the host puts forward for every client that wants to consume the service provided by the host. Now what is a contract? We mentioned about some restrictions when I was explaining our Forex requirement scenario earlier, remember? A contract is a document that is published to the client whenever the client requests for a service. The contract document lists all details about the service e.g. name and location of the service, list of operations available in the service, the in and out message requirements for communication, port types and so on. Every client must send a request exactly as described in the contract document, otherwise the service will not be rendered. In our example, the Forex webservice extends only one operation, namely GetConversionRate. If you try the URL in a browser, you will be shown details as below. Btw, to explain it further, WSDL stands for Web Service Description Language. That explains it all!

In fact, when we created the service and run it, it displayed us the list of available operations, remember? In the same screen, there is a link on top as Service Description.  If you had tried the link, you must have visited the WSDL file already for our service.

The DiscoveryDocumentReference url is http://localhost/Forex/Service.asmx?disco. It contains details on where the service can be found. Try the URL in browser.

Now that the web reference is added, my client application can consume the web service. Here is a code snippet from the client application:
public partial class _Default : System.Web.UI.Page 
   protected void Page_Load(object sender, EventArgs e)
     Forex.ForexService forex = new Forex.ForexService();
     Response.WriteLine("1 US Dollar = " + forex.GetConversionRate("USD", "INR").ToString() + " Indian Rupees");
     Response.WriteLine("1 Euro = " + forex.GetConversionRate("EUR", "INR").ToString() + " Indian Rupees");
The code is easy enough to understand, but to put it in short: we have created an object of the class (the service class) and called the GetConversionRate method. The result will be two lines on the page, something like:

1 US Dollar = 49.2 Indian Rupees
1 Euro = 67.3 Indian Rupees

Let us summarize what we know about web services so far. A web service is a code segment placed on a host (server) that can be invoked by a client using an HTTP URL. The host publishes a contract that defines what operations are available to be invoked by client, what inputs are required and in what format the result can be expected. A client can consume a web service by using the reference to the service and invoking its method.

In our example, we used two strings as input and a double as output. In the next post, I will talk about serialization and using more complex types as parameters.