When the Client Doesn t Use .NET


When the Client Doesn’t Use .NET

All of the types of clients we’ve looked at in this chapter assume that you have the .NET Framework installed, but not all people will have it. Interoperability is the key to Web services, so you need to know how to build clients around a .NET Web service when .NET is not available on the client. We’ll focus on two common scenarios, one in which the developer is using a legacy Visual Studio language such as Visual Basic 6.0 or Visual C++ 6.0, and one in which the developer is using ASP.

Consuming a Web Service from Old COM Applications

There are two common ways of enabling your COM applications to consume a Web service. You can use the SOAP Toolkit to build in the functionality, or you can get Microsoft XML Core Services (MSXML) to do it for you. We’ll look briefly at both. Once again, we’ll use our weather report example, but this time we’ll call it using a Visual Basic 6.0 application to show how you can use either approach.

Using the SOAP Toolkit

The SOAP Toolkit is a handy add-on that allows you to add Web services to your COM applications and components. It provides a COM-based API that can be used with languages such as Visual Basic 6.0 and Visual C++ 6.0. The SOAP Toolkit is currently in its third revision, and the latest version (3.0 as of this writing) is available for free from Microsoft at http://msdn.microsoft.com/library/default.asp?URL=/downloads/list/websrv.asp.

You can use the SOAP Toolkit 3.0 to both create clients capable of connecting to Web services and to expose methods from existing COM applications as Web services. The Toolkit consists of two main components—a client-side component called SOAPClient, which can invoke operations described in the WSDL document, and a server-side component that maps the Web service methods to COM object method calls. This second component allows you to expose your Web services. In this chapter, we’ll focus only on the SOAPClient component.

For our example, we just need to create a standard .exe file. As we did with the Web Forms application, we simply add a text box, a button, and two labels. Before we can add any code, we must supply a reference to the SOAP Type Library 3.0 using the References dialog box, as shown in Figure 8-12. This will ensure that the SOAPClient component is available for use in Visual Basic 6.0.

click to expand
Figure 8-12: Supplying a reference

For the sorting of the XML code that is returned by the Web service, we should also add the MSXML 3.0 or 4.0 library (depending on which is available). We then add the following code to the button’s click event handler:

Private Sub Command1_Click()     Dim SOAP As MSSOAPLib30.SoapClient30     Set SOAP = New MSSOAPLib30.SoapClient30     SOAP.MSSoapInit "http://www.webservicex.net/usweather.asmx?WSDL"     Dim weather As String     weather = SOAP.GetWeatherReport(Text1.Text)     Dim strDoc As String     strDoc = ""     Dim XMLDocument As MSXML2.DOMDocument     Set XMLDocument = New MSXML2.DOMDocument          XMLDocument.LoadXml (weather)     Set XMLRoot = XMLDocument.documentElement     For loop1 = 0 To XMLRoot.childNodes.length - 1         Set XMLParentNode = XMLRoot.childNodes(loop1)                   For loop2 = 0 To XMLParentNode.childNodes.length - 1             Set XMLNode = XMLParentNode.childNodes(loop2)             If XMLNode.nodeName = "#text" Then                 strDoc = strDoc + XMLNode.parentNode.nodeName + " - " _                     + XMLNode.Text + vbCrLf             Else                 strDoc = strDoc + XMLNode.nodeName + " - " _                     + XMLNode.Text + vbCrLf             End If         Next      Next Label2.Caption = strDoc End Sub

The code is simple enough: after the error handler, the first two lines just create an instance of the SoapClient30 object called SOAP. We load the WSDL of the service into the object, and then we can call the methods of the Web service, just as we would in .NET.

In fact, the SoapClient30 object takes three parameters, all as strings. The first is the WSDL reference to the Web service, the second is the port name, and the third is the WSML file. The second and third parameters are optional if you specify only a WSDL document containing one service with one SOAP port. For this example, we supplied only the first parameter. The second part of the code just iterates through the elements in the XML that is returned, displaying the element followed by the text.

When you run the code, it returns the information to your application as shown in Figure 8-13.

click to expand
Figure 8-13: Legacy Visual Basic 6.0 application accessing a .NET Web service

Error handling is also done slightly differently in a COM client because you must rely on the SOAP Client object to get information from the SOAP Fault element for you. You can add an On Error Go To section to the code to return this information, followed by an error handler section:

On Error Goto Err  Err:     Dim errMsg As String     Msg = Err.Description + vbcrlf _         + "Fault Code –" + soap.FaultCode + vbcrlf     Msg = Msg + "Fault String –" + soap.FaultString     MsgBox msg, vbCritical

This code should enable you to more elegantly handle any problems with the Web service that might arise.

Using MSXML

Using MSXML to consume the Web service is just as easy. You don’t need a reference to the SOAP Type Library—you just need the reference to the MSXML library. The code varies only slightly:

Private Sub Command1_Click()     Dim XMLDocument As MSXML2.DOMDocument     Set XMLDocument = New DOMDocument     XMLDocument.async = False     Dim wsURL As String     wsURL = "http://www.webservicex.net/usweather.asmx" _         + "/GetWeatherReport?zipcode=" + Text1.Text     Label2.Caption = wsURL     XMLDocument.Load (wsURL)     Dim strDoc As String     strDoc = ""     Dim strDoc2 As String     strDoc2 = ""     strDoc2 = XMLDocument.lastChild.Text     Dim XMLDocument2 As MSXML2.DOMDocument     Set XMLDocument2 = New MSXML2.DOMDocument     XMLDocument2.LoadXml (strDoc2)     Set XMLRoot = XMLDocument2.documentElement     For loop1 = 0 To XMLRoot.childNodes.length - 1         Set XMLParentNode = XMLRoot.childNodes(loop1)                   For loop2 = 0 To XMLParentNode.childNodes.length - 1             Set XMLNode = XMLParentNode.childNodes(loop2)             If XMLNode.nodeName = "#text" Then                 strDoc = strDoc + XMLNode.parentNode.nodeName + " - " _                     + XMLNode.Text + vbCrLf             Else                 strDoc = strDoc + XMLNode.nodeName + " - " _                     + XMLNode.Text +  vbCrLf             End If     Next Next Label2.Caption = strDoc End Sub

We created an instance of the MSXML2.DOMDocument object, set its async property to false to enable the document to finish loading before processing continues, and then we supplied the whole URL of the particular Web method along with the query information and used the load method to load the resulting text. However, as you can see if you query the method directly by browsing the URL http://www.webservicex.net/usweather.asmx/GetWeatherReport?zipcode=98052, the XML is in fact wrapped in a <string> element (as shown in Figure 8-14).

click to expand
Figure 8-14: Viewing the XML returned by the USWeather Web service in Internet Explorer

The XML elements returned from the Web service have to be extricated from the <string> element (something .NET can be made to do automatically with its extended XML classes) before they can be separated out. To do this, we create a second DOMDocument object and read the last child from the first DOMDocument object into it before we can iterate through each element, separating out the element names and matching them with the data they contain.

Despite the extra layer of work required with this particular Web service (not all Web services would return their information in this way), it is still straightforward to return the data from the Web service to our Visual Basic 6.0 client.

Using ASP 2.0 and 3.0

Since Microsoft Internet Information Services (IIS) 3.0, classic ASP has been standard on most Windows platforms. (Windows ME and Windows XP Home Edition are the notable exceptions, but it is possible to install Personal Web Server, which comes with ASP, on Windows ME.) It’s also a given that most Windows Internet service providers (ISPs) will use IIS. Unfortunately, not all ISPs will have upgraded to .NET, and among those that have upgraded, plenty will charge more for the use of .NET-based facilities. Therefore, many small businesses and home consumers will still be using ASP instead of ASP.NET. Fortunately, it’s possible—and easy—to add Web services to classic ASP pages.

If we go back to our Web Form weather forecast example from earlier in this chapter, it’s a simple task to change the ASP.NET client to ASP. Of course, we have to move back to ASP’s classic request/response two-page structure, something that’s been done away with in ASP.NET, but otherwise there isn’t much difference.

The first page is an HTML form that takes the ZIP Code and submits it to our ASP page:

<html>   <head>   </head>   <body>     Enter the zip code of the region you want a weather forecast for:     <form method="get" action="aspwebservice.asp">       <input type="text" name="zipcode">       <input type="submit" value="Click here">     </form>   </body> </html>

There’s nothing special in this page—just a simple text box control called zipcode and a button for submitting the HTML form. The HTML form is submitted using the HTTP-GET method, and the page that is called up is aspwebservice.asp. It’s the ASP code in this page that’s of most interest to us:

<%@language = JScript%> <html> <head> <%     var userRequest = Server.CreateObject("MSXML2.XMLHTTP")     var XMLDocument = Server.CreateObject("MSXML2.DOMDocument")         var XMLDocument2 = Server.CreateObject("MSXML2.DOMDocument")     XMLDocument.async = false     var webservURL = "http://www.webservicex.net/usweather.asmx/"         + "GetWeatherReport?ZipCode=" + Request.QueryString("Zipcode")     userRequest.Open ("GET", webservURL, false)     userRequest.Send()     var strDoc = "" XMLDocument.load(userRequest.responseXML)         var strDocument = XMLDocument.lastChild.text     XMLDocument2.loadXML(strDocument)     XMLRoot = XMLDocument2.documentElement          for (loop1=0; loop1 <= XMLRoot.childNodes.length-1; loop1++)     {                                     XMLParentNode = XMLRoot.childNodes(loop1);          for (loop2=0; loop2<=XMLParentNode.childNodes.length-1; loop2++)         {                 XMLNode = XMLParentNode.childNodes(loop2);             if (XMLNode.nodeName == "#text")             {                 strDoc += "<b>" + XMLNode.parentNode.nodeName +                      "</b> - " + XMLNode.text + "<br>"             }             else             {                 strDoc += "<b>" + XMLNode.nodeName + "</b> - " +                      XMLNode.text + "<br>"             }         }     }     userRequest = null     XMLDocument = null %> </head> <body> The weather forecast is: <br> <br> <%     Response.Write(strDoc) %> </body> </html>

As you can see, we’re using JScript—it’s closer to the C# we’ve been using in the Web Forms example. The first seven lines do all the work. The first three lines create instances of three new objects:

var userRequest = Server.CreateObject("MSXML2.XMLHTTP") var XMLDocument = Server.CreateObject("MSXML.DOMDocument") var XMLDocument2 = Server.CreateObject("MSXML2.DOMDocument")

The first object, XMLHTTP, allows a client to make a request, receive a response, and parse that response using the XML document model. This is really the only significant difference from our Web Forms example, in which you could query an instantiation of the proxy class directly. Here we just send a request to our Web service and get the response back as an XML document.

The second object is an instance of XMLDocument. This second object is used to store the XML that is returned by the response of the Web service. The third object is a second instance of XMLDocument. When the response is sent back by the Web service, it wraps the XML tags in a <string> element, and it’s impossible to navigate this structure because it uses XMLDOM; with the more complex XML processing facilities of .NET, this wasn’t an issue. We now have to split out this XML as text and load it into a second XML document, minus the <string> tag, before we can navigate it.

Next we have to configure the objects correctly so we can send a request to the Web service:

XMLDocument.async = false; var webservURL = "http://www.webservicex.net/usweather.asmx/"     + "GetWeatherReport?ZipCode=" + Request.QueryString("Zipcode")

XMLDocument has an async property that must be set to false so the code will wait for the XMLDocument object to be loaded in its entirety before processing it. We create a URL to query the service with. This URL is made up of the service name followed by the name of the method, GetWeatherReport, followed by the request we want to submit to the Web service. The query string has the name ZipCode and takes its value from the reply the user posted in the HTML form. In the next two lines, we submit the request using the URL and false property, via the HTTP-GET protocol:

userRequest.Open("GET", webservURL, false);     userRequest.Send();

The response is then loaded into the XMLDocument object, and a text version of that response is displayed on the page. In Figure 8-15, we supply the ZIP Code 60645 for the Evanston district of Illinois.

click to expand
Figure 8-15: ASP Web service client

Once again, we’ve also used the DOM to separate out each element so we can view them all on the screen in a readable format. You can choose to process the XML that is returned in any way you like—we’ve chosen to make the element names bold.

As you can see, it’s relatively easy to query a Web service using ASP and then parse the XML response and display it in an ASP page.




Programming Microsoft. NET XML Web Services
Programming MicrosoftВ® .NET XML Web Services (Pro-Developer)
ISBN: 0735619123
EAN: 2147483647
Year: 2005
Pages: 172

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net