Chapter 16. Creating .NET Web Service Clients

Many of the early Web services products are heavily oriented to the server side of the transaction. Microsoft .NET is different in this regard in that it provides considerable support to the client, or consuming side, of the task at hand.

Web services are created in such a way that any SOAP-compliant client can access them. There are some mechanical considerations to deal with, however, when you start creating a client. This hour shows you how .NET languages can use the framework as a foundation for creating clients that consume the Web services that we write. In addition, you will create several more sophisticated Web services and the clients that communicate with them. You will learn specifically how to

  • Create a client that requests data.

  • Return a structure from a Web service.

  • Create a Web services client.

  • Create a client to access a Web service from another company.

Exchanging Complex Data

You could write a program that generates SOAP messages by concatenating characters together one at the time. Although this would be possible to achieve, it would be tedious and unnecessary for most applications. It is far easier to use a combination of a tool and the WSDL document for service to generate the code for that client. Even better than that is the .NET approach in which the framework can dynamically read the WSDL in order to create the correct SOAP messages. In this section, we will step through the process of creating a simple Web service and a client that can access it.

Creating a Web Service to Connect with

Creating a Web Service to Connect with

The first example that we will work will demonstrate how user-defined data types, sometimes called structures or objects, can be passed from a Web service to a client. We can define a simple structure within a Web service as shown in Listing 16.1.

Example 16.1. The StructService1.asmx File

Imports System.Web.Services

<WebService(Namespace:="http://www.samspublishing.com")> _
Public Class StructService1
    Inherits System.Web.Services.WebService

#Region " Web Services Designer Generated Code "

    Public Structure Employee
        Dim Name As String
        Dim Age As Integer
        Dim SSN As String
        Dim HDate As Date
    End Structure

    <WebMethod()> Public Function GetEmployee() As Employee
        Dim emp As Employee

        emp.Name = "John Libby"
        emp.Age = 48
        emp.SSN = "234-56-7890"
        emp.HDate = #1/6/1955#

        Return (emp)
    End Function

End Class

You will recognize much of this code from the examples that we worked in the last hour. The unique part of this example is the definition of a structure inside the Web service file.

   Public Structure Employee
       Dim Name As String
       Dim Age As Integer
       Dim SSN As String
       Dim HDate As Date
   End Structure

We will create a Web method to send this structure to a client. Notice that we don’t send it as individual data items, but as a unit.

   <WebMethod()> Public Function GetEmployee() As Employee
       Dim emp As Employee

       emp.Name = "Steve Potts"
       emp.Age = 48
       emp.SSN = "234-56-7890"
       emp.HDate = #1/6/1955#

       Return (emp)
   End Function

You can find the WSDL for a Web service in the Web References section of the Solution Explorer pane of the IDE. The WSDL declaration that .NET has generated for this Web service contains some interesting features, as shown here:

<types>
<s:schema elementFormDefault="qualified"
                        targetNamespace="http://www.samspublishing.com">
<s:element name="GetEmployee">
  <s:complexType />
  </s:element>
<s:element name="GetEmployeeResponse">
<s:complexType>
<s:sequence>
  <s:element minOccurs="1" maxOccurs="1"
                           name="GetEmployeeResult" type="s0:Employee" />
  </s:sequence>
  </s:complexType>
  </s:element>
<s:complexType name="Employee">
<s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
  <s:element minOccurs="1" maxOccurs="1" name="Age" type="s:int" />
  <s:element minOccurs="0" maxOccurs="1" name="SSN" type="s:string" />
  <s:element minOccurs="1" maxOccurs="1" name="HDate" type="s:dateTime" />
  </s:sequence>
  </s:complexType>
  <s:element name="Employee" type="s0:Employee" />
  </s:schema>
  </types>

Notice that the GetEmployeeResponse element contains a complexType.

<s:element name="GetEmployeeResponse">
<s:complexType>
<s:sequence>
  <s:element minOccurs="1" maxOccurs="1"
                           name="GetEmployeeResult" type="s0:Employee" />

The complexType is composed of simple types.

<s:complexType name="Employee">
<s:sequence>
  <s:element minOccurs="0"
            maxOccurs="1" name="Name" type="s:string" />
  <s:element minOccurs="1"
            maxOccurs="1" name="Age" type="s:int" />
  <s:element minOccurs="0"
            maxOccurs="1" name="SSN" type="s:string" />
  <s:element minOccurs="1"
            maxOccurs="1" name="HDate" type="s:dateTime" />
  </s:sequence>
  </s:complexType>

Notice that each element in the complexType represents a field in the structure that we want to convey.

The messages are defined here:

<message name="GetEmployeeSoapIn">
  <part name="parameters" element="s0:GetEmployee" />
  </message>
<message name="GetEmployeeSoapOut">
  <part name="parameters" element="s0:GetEmployeeResponse" />
  </message>

The bindings for SOAP are shown here:

<binding name="StructService1Soap" type="s0:StructService1Soap">
  <soap:binding transport=
    "http://schemas.xmlsoap.org/soap/http" style="document" />
<operation name="GetEmployee">
  <soap:operation soapAction=
    "http://www.samspublishing.com/GetEmployee" style="document" />
<input>
  <soap:body use="literal" />
  </input>
<output>
  <soap:body use="literal" />
  </output>
  </operation>
  </binding>

The WSDL service element is defined, which contains the URL of the Web service.

<service name="StructService1">
<port name="StructService1Soap" binding="s0:StructService1Soap">
  <soap:address location=
       "http://localhost/StructService/StructService1.asmx" />
  </port>

Creating the Web Services Client

Creating the client for the StructService1 Web service is easy to do using Visual Basic .NET. The first step is to create a new Windows Application project that contains a form. Using the toolbox, add four text boxes called txtName, txtAge, txtSSN, and txtHireDate to the form. The code for this form is shown in Listing 16.2.

Example 16.2. The Form1.vb File

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "
#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim WS As New localhost.StructService1()

        Dim employee1 As localhost.Employee

        employee1 = WS.GetEmployee()

        txtName.Text = employee1.Name
        txtAge.Text = employee1.Age
        txtSSN.Text = employee1.SSN
        txtHireDate.Text = employee1.HDate

    End Sub
End Class

We chose the Form1_Load event procedure to populate the form with information retrieved from the StructService1 Web service. The first thing that we must do is make the connection with the service. The WSDL file becomes part of the client project when you add the Web reference to the project. Until then, the name StructService1() will be meaningless.

   Dim WS As New localhost.StructService1()

The Employee type is known because it exists in the WSDL.

   Dim employee1 As localhost.Employee

The call to retrieve the employee is made using the handle to the Web service class.

   employee1 = WS.GetEmployee()

We display the values on our form by referencing the employee’s information using the Visual Basic dot notation. The text box’s Text property controls what is displayed. By assigning a value to it, you cause it to be displayed on the screen.

    txtName.Text = employee1.Name
    txtAge.Text = employee1.Age
    txtSSN.Text = employee1.SSN
    TxtHireDate.Text = employee1.HDate

Adding the Web reference is the only complicated part of this example. The easiest way to do this is to choose Add Web Reference from the Project Menu. The Add Web Reference dialog box will appear as shown in Figure 16.1.

The Add Web Reference dialog box gives you an opportunity to specify a connection to a Web service.

Figure 16.1. The Add Web Reference dialog box gives you an opportunity to specify a connection to a Web service.

Now, all that is left is to run the StructClient application by pressing the F5 key or by choosing Start from the Debug menu. The result is shown in Figure 16.2.

You can display information gathered from a Web service on a Visual Basic form.

Figure 16.2. You can display information gathered from a Web service on a Visual Basic form.

Compared to the complicated process required by some tools, the Visual Basic .NET approach is very simple to learn and use.

Discovering a Web Service

Up to this point, we have limited our examples to Web services that we have created. Much of the development that you will do in your career will consume Web services written by others. You can call the methods that those services expose almost as easily as you can call methods on the services running on your own machine.

The Visual Studio IDE provides a built-in way to find Web services to communicate with: the Add Web Reference dialog box. A Web reference is a reference to an object that is located somewhere on the Web. When we add a Web reference to a project, we are asking .NET to add the “plumbing” needed for your application to make requests of this remote reference and to get responses from them. To do this, create a new Windows Application project. When the skeleton project appears in the Solution Explorer, right-click on the project name and choose Add Web Reference from the context menu. When the dialog box appears, click on the UDDI Directory hyperlink.

This will bring up the dialog box shown in Figure 16.3.

A UDDI directory can help you find a Web service that you need for your project.

Figure 16.3. A UDDI directory can help you find a Web service that you need for your project.

Type "IBM" in the Provider Name text box, and then click the Search button. This will retrieve a number of possible selections as shown in Figure 16.4.

A single provider might make dozens of different Web services available for you to use.

Figure 16.4. A single provider might make dozens of different Web services available for you to use.

After some frustration with the fact that we couldn’t find any Web services that provided decent references, we decided to copy the URL from one of these entries as shown here:

http://dwdemos.alphaworks.ibm.com/IBM_WSI_Sample/

We copied and pasted this link into the address bar of our dialog and pressed Enter. The following page appeared in the Add Web Reference dialog box as shown in Figure 16.5.

The Apache Axis Web services engine is employed by IBM to serve its demo Web services.

Figure 16.5. The Apache Axis Web services engine is employed by IBM to serve its demo Web services.

Next, we chose the View the List of the Deployed Web Services hyperlink, which caused the screen shown in Figure 16.6 to appear.

The IBM site offered a variety of demonstration-quality Web services to connect to.

Figure 16.6. The IBM site offered a variety of demonstration-quality Web services to connect to.

Because we wanted a simple Web service for this example, we chose the first one, the Version Web service. This caused the dialog box to display the WSDL for that service to appear in the left panel, as shown in Figure 16.7.

Finding the WSDL for the service that we want to connect to is the goal of the search.

Figure 16.7. Finding the WSDL for the service that we want to connect to is the goal of the search.

We clicked on the Add Reference button at the bottom of this dialog box to add this WSDL to our project. Figure 16.8 shows the Solution Explorer window with the Version.wsdl file listed under the Web References tree.

Once the WSDL is added to a project, all the information needed to communicate with the service is present.

Figure 16.8. Once the WSDL is added to a project, all the information needed to communicate with the service is present.

The WSDL document itself is fairly easy to understand. Listing 16.3 shows what it looks like.

Example 16.3. The Version.wsdl File

<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://dwdemos.alphaworks.ibm.com/IBM_WSI_Sample/services/Version"
xmlns:s=http://www.w3.org/2001/XMLSchema
               xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace=
      "http://dwdemos.alphaworks.ibm.com/IBM_WSI_Sample/services/Version"
xmlns="http://schemas.xmlsoap.org/wsdl/">
   <types />
   <message name="getVersionResponse">
     <part name="getVersionReturn" type="s:string" />
   </message>
   <message name="getVersionRequest" />
   <portType name="Version">
     <operation name="getVersion">
       <input name="getVersionRequest" message="tns:getVersionRequest" />
       <output name="getVersionResponse"
                                       message="tns:getVersionResponse" />
     </operation>
   </portType>
   <binding name="VersionSoapBinding" type="tns:Version">
     <soap:binding transport=http://schemas.xmlsoap.org/soap/http
                                                           style="rpc" />
     <operation name="getVersion">
       <soap:operation soapAction="" />
       <input name="getVersionRequest">
         <soap:body use="encoded"
namespace=
   "http://dwdemos.alphaworks.ibm.com/IBM_WSI_Sample/services/Version"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </input>
      <output name="getVersionResponse">
        <soap:body use="encoded"
namespace=
    "http://dwdemos.alphaworks.ibm.com/IBM_WSI_Sample/services/Version"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
      </output>
    </operation>
   </binding>
   <service name="VersionService">
     <port name="Version" binding="tns:VersionSoapBinding">
        <soap:address location=
   "http://dwdemos.alphaworks.ibm.com/IBM_WSI_Sample/services/Version" />
      </port>
   </service>
</definitions>
The Version.wsdl File

The binding tells us how to communicate with this service. We are going to use SOAP and the rpc style on an operation (method) called getVersion.

  <binding name="VersionSoapBinding" type="tns:Version">
    <soap:binding transport=http://schemas.xmlsoap.org/soap/http
                                                 style="rpc" />
    <operation name="getVersion">
      <soap:operation soapAction="" />
      <input name="getVersionRequest">
        <soap:body use="encoded"

The address that we will use to access the SOAP version of this Web service is shown here:

    <port name="Version" binding="tns:VersionSoapBinding">
      <soap:address location=
 "http://dwdemos.alphaworks.ibm.com/IBM_WSI_Sample/services/Version" />
    </port>

The information in this document is sufficient for .NET to communicate with this Web service directly using SOAP.

Writing a Client for the Discovered Service

Now that we have a Web reference to a service on the IBM site, we can try and make calls to it. The code in Listing 16.4 gives us a client to test it with.

Example 16.4. The Version’s Form1 Class

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Private Sub Form1_Load(ByVal sender As System.Object,
                 ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object,
                ByVal e As System.EventArgs) Handles Button1.Click
        Dim WS As New com.ibm.alphaworks.dwdemos.VersionService()

        Dim s1 As String

        s1 = WS.getVersion()
        txtVersionInfo.Text = s1

    End Sub

End Class

Add a button, Button1, and a text box, txtVersionInfo, to the form and place this code in the Form1 class. Access to the Web service is provided by the fact that the Web reference for this service has been added to the project and the following line of code has been included:

Dim WS As New com.ibm.alphaworks.dwdemos.VersionService()

Here, we are creating a handle to an object located on another computer somewhere on the Internet. We use that handle to make a call to the method of that service.

   s1 = WS.getVersion()

The return value from this is a String, so we will assign it directly to the Text property of a text box.

   txtVersionInfo.Text = s1

You can run this example by choosing Start from the Debug menu or pressing the F5 key. After the window appears, click on the Get Version button. Figure 16.9 shows what the result looks like.

The Version Web service communicates information about the SOAP engine to the client.

Figure 16.9. The Version Web service communicates information about the SOAP engine to the client.

Notice that we are using a .NET client to talk to an Apache Axis Web service, without any special effort on our part. The WSDL provides all the information that we need to communicate. Notice also that we have no information about the language that the Version Web service was written in, nor do we need to know it. The SOAP engine on the server translates the SOAP messages into the programming language of the server in the same way that the CLR translates the SOAP messages into Visual Basic for us.

Summary

In this hour, you learned how to create Web service clients using Visual Basic and the .NET platform. You first learned how to create a client that could make a request and receive a complex data type.

After that, you learned how to use Visual Studio to create a client to connect to a Web service that we found by searching directory services.

The .NET approach to creating clients is by far the most advanced of any on the market. It will be interesting to see whether the current Web service development community will be open to a Microsoft solution, given that so many of them sided with Sun Microsystems in the “Java Wars” of the past decade.

Q&A

Q

Why is Visual Studio .NET considered to be a good client-creation platform?

A

Microsoft is known for its client-side technology, and it isn’t surprising that its client Web services tools are among the best and easiest to use.

Q

How can a client be generated from just the WSDL? Where does the rest of the information come from?

A

There is no need for any other information. A properly created WSDL document contains all the information needed for successful connection.

Workshop

The Workshop is designed to help you review what you’ve learned and begin learning how to put your knowledge into practice.

Quiz

1.

What is the goal of the discovery process?

2.

What is the .NET approach to creating a client?

3.

What type of data can be sent to a client?

Quiz Answers

1.

To locate a WSDL document for the remote service.

2.

The .NET framework exposes a class called System.Web.Services.WebServices that handles most of the communication details for you.

3.

Web services can return data of arbitrary complexity. The WSDL describes the data so that your client program can be written to receive it.

Activities

1.

Create a calculator Web service and a client on your computer. Make the Web service support add() and subtract() methods. Create a client that can gather this information from the user and display the answer.

2.

Create a client that accesses a Web service that you find over the Internet or using the discovery features of Visual Studio.

 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset