Consuming an XML Web Service
By Doug Seven
Published: 11/14/2001
Reader Level: Beginner
Rated: 4.00 by 1 member(s).
Tell a Friend
Rate this Article
Printable Version
Discuss in the Forums

In the previous tutorial I showed you how to build a very basic XML Web Service. In this tutorial I will show you how to build a consumer for that XML Web Service.

con·sum·er [kon sumer] (plural con·sum·ers) noun
organism that feeds on others: in an ecological community or food chain, an organism that feeds on other organisms, or on material derived from them.
Encarta® World English Dictionary © & (P) 1999 Microsoft Corporation. All rights reserved. Developed for Microsoft by Bloomsbury Publishing Plc.

An XML Web Service consumer is an application that invokes the methods of an XML Web Service made available by a provider; the consumer feeds on the data derived from the XML Web Service provider. A consumer application may be another Web application, XML Web Service, Windows desktop application, or any other type of application with access to the XML Web Service using HTTP.

Overview

The steps to consuming an XML Web Service are:

  1. Discover the XML Web Service.
  2. Create a proxy of the XML Web Service.
  3. Create an instance of the proxy and invoke a method.

1. Discover the XML Web Service

The discovery of an XML Web Service will typically be done on a business-to-business level. In other words, two businesses will agree to exchange data using an XML Web Service, and the provider of the service will inform the consumer about where to find the service.

Another means of discovering an XML Web Service is by using the Universal Description, Discovery, and Integration service (http://www.uddi.org). This is a registry of XML Web Services provided by a number of different companies. Currently two member companies of UDDI, Microsoft and IBM, provide search engines for finding an XML Web Service that suits your need. Businesses that are exposing XML Web Services can be listed in the UDDI registry, detailing information about the company and the XML Web Services they are making available.

Figure 3.1 shows the UDDI registry entry for DotNetJunkies.com:

Figure 3.1

The result of the discovery process should be the URL to the Web Service Description Language (WSDL) document. The WSDL is an XML document that describes the XML Web Service. This is basically the contract that the consumer agrees to; the WSDL states:

  • The URL for invoking the XML Web Service.
  • The Web methods available.
  • The input arguments expected and their data types for each Web method.
  • The output data type for each Web method.

2. Create a Proxy

Proxy, by definition, is the function, power, or capacity to substitute for another. This definition is perfect for an XML Web Service proxy. The proxy is a class on the local server that exposes the same interfaces as the XML Web Service. The proxy acts as a local substitute for the XML Web Service, and handles the calls to the XML Web Service to invoke the specified Web method.

Using the .NET Framework we can easily create a proxy class with a utility named WSDL.exe. This utility is shipped with the .NET Framework SDK, and is a command-line utility. The WSDL.exe utility is used to parse the XML Web Service WSDL and automatically generate a proxy class for the service.

3. Create an Instance and Invoke

Once we have a proxy we can, anywhere in our application, create an instance of the proxy class and invoke one of its methods.

When a method of the proxy is invoked, the proxy calls out to the XML Web Service and invokes the same method. The XML Web Service returns the output to the proxy instance in the consumer application. The proxy can then expose the output data to the original caller as if the method were invoked locally. This is seen in Figure 3.2.

Figure 3.2

Available Protocols

XML Web Service methods can be invoked using, as of this writing, one of three protocols, HTTP GET, HTTP POST, or SOAP (over HTTP).

HTTP Get

Using HTTP GET any input arguments for the Web method are passed in the request query string. This limits HTTP GET to only being available for Web methods that take no inputs, or only inputs of primitive types that can be passed in the query string, such as strings, integers, doubles, etc.

Using HTTP GET to invoke the SayHello() Web method from the last tutorial, the URL would be:

http://localhost/myservice.asmx/SayHello?YourName=Doug+Seven

Using HTTP GET is shown in Figure 3.3.

Figure 3.3

HTTP Post

Using HTTP POST is similar to using HTTP GET, however, the Web method inputs are passed in the HTTP Request body, not in the URL. The same restrictions on data types as HTTP GET apply to HTTP POST.

SOAP

A SOAP message can be used to invoke the Web method. The inputs are passed to the XML Web Service in the SOAP message body - the return data is passed back to the consumer in the body of a SOAP message. The SOAP message can be passed to the provider using either HTTP or HTTPS (as of .NET Framework Release Candidate).

Listing 3.1 shows the SOAP message used to invoke the SayHello() Web method.

Listing 3.1

POST myservice.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: 72
SOAPAction: "http://tempuri.org/SayHello"

<?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>
  <SayHello xmlns="http://tempuri.org/">
    <YourName>Doug Seven</YourName>
  </SayHello>
</soap:Body>
</soap:Envelope>

Listing 3.2 shows the SOAP message that is returned to the consumer from the XML Web Service.

Listing 3.2

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: 86

<?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>
  <SayHelloResponse xmlns="http://tempuri.org/">
    <SayHelloResult>Hello, Doug Seven</SayHelloResult>
  </SayHelloResponse>
</soap:Body>
</soap:Envelope>

Proxy Clients and WSDL.exe

To build a proxy client we can use the WSDL.exe utility - of course we could also code the proxy client ourselves, but why do that when a utility can do it for us. WSDL.exe is a command-line utility that we can invoke and it will generate a proxy client class based on the WSDL document of the XML Web Service we are creating a proxy for.

Note: Visual Studio .NET uses the WSDL.exe utility to create proxy clients as well, but this is abstracted under the "Add Web Reference" Project menu option. We will build a consumer application using Visual Studio .NET in an upcoming tutorial.

The command to build a proxy class for the MyService XML Web Service from Chapter 2 would look like this:

wsdl.exe /out:MyServiceProxy.cs http://localhost/MyService.asmx?WSDL

This command will execute the WSDL.exe utility and create a file named MyServiceProxy.cs in the same directory that this command was executed from. The MyServiceProxy.cs file contains the proxy class for the MyService XML Web Service at http://localhost/MyService.asmx; it was built using the WSDL document for this XML Web Service as specified using the ?WSDL query string modifier.

WSDL.exe

Lets break down the WSDL.exe utility. The syntax for executing a WSDL.exe command is (the italic words are replace by proper values):

wsdl.exe /language:language /protocol:protocol
/namespace:Namespace /out:filename
/username:username /password:password /domain:domain
/appsettingurlkey:keyname <url or path>

Note: The WSL.exe command cannot include line breaks. It must be one continuous line.

Not all of the arguments are required…in fact the only required argument is the URL or path to the WSDL document. Table 3.1 defines some of the WSDL.exe options (execute wsdl.exe /? To see a list of all of the WSDL.exe options).

Table 3.1

Option (short form) Description
URL or Path A URL or path to the WSDL, XSD schema or .discomap document.
/language: (/l:) Specifies the language to use when generating the proxy class. The default is CS (C#). Other options are VB (Visual Basic .NET), JS (JScript .NET) or a fully-qualified name for a class implementing System.CodeDom.Compiler.CodeDomProvider.
/namespace: (/n:) Specifies the namespace the proxy class should be created in. The default is the global namespace.
/out: (/o:) Specifies the name of the file that will be created. The default name is derived from the XML Web Service name.
/protocol: Specifies the protocol the proxy will use when invoking the XML Web Service. The default is SOAP - other options are HttpGet and HttpPost.
/username: (/u:)
/password: (/p:)
/domain: (/d:)
Specifies the credentials to use when connecting to a server that requires authentication.
/appsettingurlkey: (/urlkey:) Specifies the name of a configuration file <appsettings> key. This key specifies the URL to use when invoking methods on the XML Web Service. The URL in the key/value will be used if it is available, otherwise the URL that was used to make the proxy will be used.

The Proxy

We can create a proxy client using the following command (in one continuous line):

wsdl.exe /l:cs /out:MyServiceProxy.cs /n:MyClient http://www.dotnetjunkies.com/services/MyService.asmx?WSDL

The resulting file looks like Listing 3.3.

Listing 3.3

//--------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.0.2914.16
//
// Changes to this file may cause incorrect behavior and will be
// lost if the code is regenerated.
// </autogenerated>
//--------------------------------------------------------------------
//
// This source code was auto-generated by wsdl, Version=1.0.2914.16.
//

namespace MyClient {
  using System.Diagnostics;
  using System.Xml.Serialization;
  using System;
  using System.Web.Services.Protocols;
  using System.Web.Services;

  [System.Web.Services.WebServiceBindingAttribute(
    Name="MyServiceSoap",
    Namespace="http://tempuri.org/")]
  public class MyService :
    System.Web.Services.Protocols.SoapHttpClientProtocol {

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    public MyService() {
      this.Url =
        "http://www.dotnetjunkies.com/services/MyService.asmx";
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.Web.Services.Protocols.SoapDocumentMethodAttribute(
      "http://tempuri.org/SayHello",
      Use=System.Web.Services.Description.SoapBindingUse.Literal,
      ParameterStyle=
      System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    public string SayHello(string YourName) {
      object[] results = this.Invoke("SayHello", new object[] {
        YourName});
      return ((string)(results[0]));
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    public System.IAsyncResult BeginSayHello(string YourName,
      System.AsyncCallback callback, object asyncState) {
      return this.BeginInvoke("SayHello", new object[] {
        YourName}, callback, asyncState);
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    public string EndSayHello(System.IAsyncResult asyncResult) {
      object[] results = this.EndInvoke(asyncResult);
      return ((string)(results[0]));
    }
  }
}

We can see in the code for the proxy that it simply creates an interface for the XML Web Service. Each method invokes the specified method. The proxy class itself derives from HttpGetClientProtocol, HttpPostClientProtocol, or SoapHttpClientProtocol depending on the /protocol: option we specified when creating the proxy.

The proxy class has two additional methods for each Web method, the BeginMethod() and EndMethod() methods (BeginSayHello() and EndSayHello() in the example). These methods are used to invoke the Web methods asynchronously - without waiting for a response...sort of the fire-and-forget way to invoke a Web method. We will get into asynchronous Web method invoking later in this tutorial series.

When we compile this class into an assembly and put the DLL in the \bin directory of a Web application, we can create instances of this class and invoke its methods. To compile the proxy class we can use a command-line compiler, CSC.exe (VBC.exe for Visual Basic .NET applications), as follows:

csc.exe /t:library /out:MyClient.dll *.cs /r:System.dll,System.Web.dll

This will create a DLL named MyClient.dll, with one class, MyService. With this DLL in the \bin directory, we can create a proxy client - in this case, a Web Form.

The Client

The client for the MyService XML Web Service is relatively simple - it is a TextBox, a Button and a Label, as seen in Figure 3.4.

Figure 3.4

The Web Form has a TextBox where the Web site visitor can input their name. This value will be used as the input for the SayHello() Web method. When the "Invoke MyService" Button is clicked, it triggers a postback. In the postback handler we create an instance of the MyClient.MyService proxy class, and invoke the SayHello() method. The string returned is set as the Label control's Text property.

The code for the Web Form (default.aspx) is shown in Listing 3.4.

Listing 3.4

<%@ Page Inherits="MyClient.CDefault" %>
<html>
<body>
<form runat="server">
  <b>Enter Your Name:</b>
  <asp:TextBox runat="server" id="Name" />
  <asp:Button runat="server" Text="Invoke MyService" />
  <hr noshade size="1">
  <asp:Label runat="server" id="Result" />
</form>
</html>

The code for the CDefault code behind class is shown in Listing 3.5.

Listing 3.5

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyClient
{
  public class CDefault : Page
  {
    protected TextBox Name;
    protected Label Result;

    public void Page_Load ( Object sender, EventArgs e )
    {
      if ( Page.IsPostBack )
      {
        MyClient.MyService _myService = new MyClient.MyService();
        Result.Text = _myService.SayHello ( Name.Text.Trim() );
      }
    }
  }
}

In the Page_Load() event handler we evaluate for a postback. If the current request is a postback we create an instance of MyClient.MyService and invoke SayHello(), passing in the user submitted value as the YourName argument. The returned data is set to the Result Label control's Text property.

Summary

While this chapter dealt with consuming a very simple XML Web Service, the principals are the same as if we had been consuming a complex XML Web Service. We used a proxy class to expose the XML Web Service's interface in a local object. With that local object we were able to invoke a method of the XML Web Service and catch the return data as if the method were executed locally.

In the next tutorial I will show you how to build a consumer application using Visual Studio .NET.



Marketplace
(Sponsored Links)
What are the green links?
   



 
Copyright © 2007 CMP Tech LLC |
Privacy Policy (4/10/06) | Your California Privacy Rights (4/10/06) | Terms of Service | Advertising Info | About Us | Help