perfectxml.com
 Basic Search  Advanced Search   
Topics Resources Free Library Software XML News About Us
  You are here: home »» Info Bank »» Articles » Visual Basic Developer's Guide to SOAP Saturday, 23 February 2008
 

Back to Articles Page      

        

Visual Basic Developer's Guide to SOAP



Author: Darshan Singh (darshan@perfectxml.com)
Last updated: Mar 01, 2002

 

Introduction

XML Web services are probably the hottest topic being talked so much! Atleast four conferences completely dedicated to Web services are scheduled for coming weeks; more than 20 books that focus entirely on Web services are already available and about dozen more are soon to be published; various newsgroups (hosted on develop.com, Yahoo groups, Microsoft, etc.) get hundreds of posts everyday on discussions related to SOAP and Web services! So, what are XML Web services? And what problem really they solve?

 

In simple words, XML Web services enable the distributed RPC (Remote Procedure Call) over the Internet. XML Web services facilitate invocation of an object over HTTP (or SMTP, etc.) from any platform, any language. For example, if you have a COM DLL, you can now very easily expose its methods over the Internet, so that any client, running on any platform, using any language would be able to invoke these methods. To summarize, when it comes to exposing objects over the Internet, today XML Web services are the excellent (and a lot simpler, extensible and manageable) alternative to DCOM or CORBA.

Web Services, however logically are different than traditional RPC because of Web services' loosely coupled characterstics. With RPC, it is absolutely fine to call a series of methods, passing parameters and getting results one after another; however, this approach is not feasible when the method invocation is over the Internet, as it is generally with Web Services. And hence, instead of calling a series of methods, it is recommended to reduce the method invocations and pass combined large pieces of input data parameters, when working with Web Services.

 

Many companies are rapidly adopting (using and exposing) XML Web services to enable the application integration, provide new services to the external world, or to seamlessly use the services from the outside world. One other area where XML Web services can be very useful is the Department-to-Department integration. Let's say you are the in-charge of building Intranet Web sites, you can now expose the common data requirements (employee details, product details, financial details, and so on) as XML Web services; you can then use these Web services yourself while building the intranet Web site or anybody else can use them, no matter what platform they are running on or what language they are using.

 

The three technologies that are at the heart of XML Web services include XML (of course!), HTTP, and SOAP (Simple Object Access Protocol). The plain text is portable across all platforms and hence XML can travel on all platforms without any issues; HTTP is the widely adopted transport and the core to the Internet; SOAP, a W3C specification defines a messaging scheme on how the remote method would be called and how the results would be returned. SOAP uses the XML to define the request and response documents.

 

In this article, we'll use Microsoft® SOAP Toolkit 2.0 SP 2 in Visual Basic 6.0 to write Web service clients, and then later on to enable existing COM objects as Web services. We assume you have little familiarity with XML and SOAP. Check PerfectXML XML, SOAP and Web Services focus section to learn more about these technologies.

 

Microsoft SOAP Toolkit

In order to invoke a Web service method using SOAP, it's required to build a request payload (an XML string) and send (post) it to the Web service. On the other side, the Web service then processes the input SOAP request payload, determines the method and parameters, calls the appropriate object method, receives the result from the method, builds the response payload (an XML string) and sends it to the caller. The caller can then parse the response text to get the method invocation results.

 

Example SOAP request payload:

POST /WebServices/SalesRankNPrice/BookService.asmx HTTP/1.1

Host: www.perfectxml.net

Content-Type: text/xml; charset=utf-8

Content-Length: length

SOAPAction: "http://www.perfectxml.com/NETWebSvcs/BookService/GetAmazonSalesRank"

 

<?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>

    <GetAmazonSalesRank xmlns="http://www.perfectxml.com/NETWebSvcs/BookService">

      <ISBN>string</ISBN>

    </GetAmazonSalesRank>

  </soap:Body>

</soap:Envelope>

 

 

The above text defines a POST request to host www.perfectxml.net hosting Web service at /WebServices/SalesRankNPrice/BookService.asmx and the method call (GetAmazonSalesRank) that takes a string parameter (ISBN).

 

Example SOAP response payload:

 

HTTP/1.1 200 OK

Content-Type: text/xml; charset=utf-8

Content-Length: length

 

<?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>

    <GetAmazonSalesRankResponse xmlns="http://www.perfectxml.com/NETWebSvcs/BookService">

      <GetAmazonSalesRankResult>string</GetAmazonSalesRankResult>

    </GetAmazonSalesRankResponse>

  </soap:Body>

</soap:Envelope>

 

 

If the call to Web service method succeeds, we'll get the response back as outlined above. The status of 200 indicates that our HTTP request succeeded; the returned content type text/xml indicates that SOAP response is returned as a XML string. This string once again contains SOAP Envelope and Body tags and the tag GetAmazonSalesRankResponse that encloses the results string (the Amazon.com sales rank for the book whose ISBN number was passed as part of SOAP request payload).

 

It's very important to understand the XML Namespaces (http://www.w3.org/TR/REC-xml-names/) and XML Schema (http://www.w3.org/TR/xmlschema-0/) standards in order to understand SOAP and Web services better.

 

The Microsoft SOAP Toolkit hides us from all these details and supports a simple object model that we can use to call the XML Web services and not worry about packaging/un-packaging SOAP request/response payloads. In addition it provides a Web service Wizard that allows "SOAP-enabling" any COM object DLL. Using this wizard, the methods inside any COM DLL can be turned into Web service methods that can be called from any platform over the internet. The Toolkit also provides a great debugging tool (Trace Utility, MsSoapT.exe) that allows intercepting SOAP request and response payloads. Go ahead and download this (free) great toolkit from the MSDN download area at http://msdn.microsoft.com/soap and let's begin writing some code!

 

Writing Web Service Clients Using SOAP Toolkit

Let's start with a simplest SOAP client. Start Visual Basic 6.0 (preferably SP5), and create a standard EXE project. Add reference (Project | References) to Microsoft SOAP Type Library (MSSOAP1.dll). Double click on the form and write the following code under the Form_Load method:

 

Dim objSOAPClient As New SoapClient

   

objSOAPClient.mssoapinit _

      "http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl"

   

MsgBox objSOAPClient.getQuote("MSFT")

 

How simple is that? Not much different than writing a COM client, right? That's really is the idea behind it. The above high-level API provided by the SOAP Toolkit hides us from the internals and allows using Web services as like any other COM object. What's going on under the hood is the following:

 

  • The mssoapinit method call accepts the WSDL (Web Service Description Language) URL. Based on the provided URL, it initializes the SoapClient instance so that we can call the Web service methods directly on this SoapClient instance. If you study the Delayed Stock Quotes WSDL (http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl), you'll notice that it exposes just one method named getQuote that accepts a string parameter and returns a float value. This is the method we call next using the SoapClient instance.
  • We pass the "MSFT" (ticker symbol for Microsoft) as a string parameter to getQuote Web service method and it returns a float number, which we display using an MsgBox statement. When this method is called, the toolkit builds a SOAP request payload similar to as shown below:

 

<se:Envelope

    xmlns:se="http://schemas.xmlsoap.org/soap/envelope/"     

    xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"

    xmlns:xsd="http://www.w3.org/1999/XMLSchema">

    <se:Body>

        <xns:getQuote

             xmlns:xns="urn:xmethods-delayed-quotes"     

    se:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

         <symbol xsi:type="xsd:string">MSFT</symbol>

        </xns:getQuote>

     </se:Body>

</se:Envelope>

 

On the successful execution of the method call, the toolkit receives the response payload similar to as shown below:

 

<se:Envelope  

    xmlns:se="http://schemas.xmlsoap.org/soap/envelope/"

    xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"

    xmlns:xsd="http://www.w3.org/1999/XMLSchema">

 

    <se:Body>

        <xns:getQuoteResponse

             xmlns:xns="urn:xmethods-delayed-quotes"    

   se:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

 

            <return xsi:type="xsd:float">63.63</return>

        </xns:getQuoteResponse>

   </se:Body>

 

</se:Envelope>

 

In summary, once the SoapClient instance is initialized using the WSDL URL, the Web service methods can directly be called on the SoapClient instance, which takes care of building and posting SOAP request, receiving the SOAP response and exposing the returned result value. Depending on the returned data type/value, you can directly access the value (such as in this case the float value) or use the MSXML DOM object model or SOAP Toolkit provided SOAP Message Object to process the returned message.

 

Let's look at one more example of writing SOAP client application using the toolkit.

 

This time we'll call the SalesRankNPrice Web service available at http://www.PerfectXML.net/WebServices/SalesRankNPrice/BookService.asmx. This Web service can be used to get the sales rank and/or price for any book available on Amazon and/or B&N Web sites.

 

Create a standard EXE project in Visual Basic 6.0. Add reference to SOAP type library and Microsoft XML Core Services (MSXML) 4.0.  Write the following code in the Form_Load method.

 

Dim objSOAPClient As New SoapClient

Dim objXMLResultNodes As IXMLDOMNodeList

 

objSOAPClient.mssoapinit _

   "http://www.PerfectXML.net/WebServices/SalesRankNPrice/BookService.asmx?wsdl"

 

Set objXMLResultNodes = objSOAPClient.GetAll("186100589X")

 

MsgBox "Amazon Sales Rank: " & _

                       objXMLResultNodes.Item(0).nodeTypedValue

 

MsgBox "Amazon Price: " & _

                       objXMLResultNodes.Item(1).nodeTypedValue

 

MsgBox "B&N Sales Rank: " & _

                       objXMLResultNodes.Item(2).nodeTypedValue

 

MsgBox "B&N Price: " & objXMLResultNodes.Item(3).nodeTypedValue

 

The above code is very similar to the first example, except how the returned results are processed. The mssoapinit call initializes the SoapClient instance with the WSDL URL for the SalesRankNPrice Web service. This Web service has a method called GetAll that returns the Amazon.com sales rank and price, and B&N sales rank and price, hence four values returned as four XML nodes, for the input ISBN. This method hence returns an IXMLDOMNodeList that contains four nodes. We save the GetAll method result into a variable of type IXMLDOMNodeList and then access the individual node values to get the actual sales ranks and prices.

 

Before we end this section, let's look at an ASP example of using the SOAP Toolkit. Create a new IIS virtual directory or use some existing IIS virtual directory, and create and save the following ASP page under this virtual directory:

 

<%

 

Option Explicit

 

Dim objSOAPClient

Dim objResultNodes

Dim objDetailsNodes

Dim objNode

Dim iRestrict

Dim iTotal

 

'Create the SOAPClient object using the version-dependent ProgID

Set objSOAPClient = Server.CreateObject("MSSOAP.SoapClient.1")

 

'See http://msdn.microsoft.com/library/en-us/dnsoap/html/soap_faq.asp?frame=true#soap_faq_topic0111a for details on this

objSOAPClient.ClientProperty("ServerHTTPRequest") = True

 

'Initialize the SoapClient instance with the WSDL URL

objSOAPClient.mssoapinit _

"http://www.perfectxml.net/WebServices/MusicTeachers/MusicTeachers.asmx?wsdl"

 

'Invoke the Web service method

'It returns a DataSet (two nodes list; one containing schema

' and other containing actual results)

Set objResultNodes = _

    objSOAPClient.FindMusicTeachers ("60195", "0", "0", "0", 10, 2)

 

'Get values of ResultsCount and RestrictResultCount from the Results node (node 1)

iTotal = objResultNodes.item(1).selectSingleNode("//ResultsCount").nodeTypedValue

iRestrict = _

      objResultNodes.item(1).selectSingleNode("//RestrictResultCount").nodeTypedValue

 

 

Response.Write ("Total " & iTotal & _

 " teachers found! Restricting the results to " & iRestrict & "<br><br>")

 

 

Set objDetailsNodes = objResultNodes.item(1).selectNodes("//Details")

 

'For each Music Teacher Detail node…

For Each objNode in objDetailsNodes

     Response.Write (objNode.selectSingleNode("Name").nodeTypedValue)

     Response.Write (": " & objNode.selectSingleNode("Phone").nodeTypedValue)

     Response.Write ("<br><hr size=1 color=gray width=99% align=center>")

Next

 

Set objSOAPClient = Nothing

 

%>

 

The above ASP code uses the Microsoft SOAP Toolkit to access the SearchMusicTeachers Web service available at (http://www.PerfectXML.net/WebServices/MusicTeachers/MusicTeachers.asmx). The only important points to note in the above code are the use of version-dependent ProgID and setting the ServerHTTPRequest property to true. See the SOAP Toolkit FAQ for more details on this.

Writing SOAP Server Using the Toolkit

As mentioned earlier, the SOAP Toolkit enables any COM object to be used as a Web service. The methods exposed via the COM object can readily be extended to Web service methods using the WSDL Generator Wizard (also known as SOAP Toolkit Wizard). This wizard essentially does three things:

 

  1. Creates a WSDL document for the provided COM DLL. The WSDL document describes the Web methods exposed, the parameter details and the SOAP port where the request should be posted.
  2. Creates the SOAP Handler (either an ASP page or an ISAPI listener) based on the choice you make in the final step in this wizard. In the generated WSDL the SOAP port location points to either to the ASP page or the .wsdl file itself based on if ASP handler or ISAPI listener is chose respectively. While ASP page is simple to work with and easy to understand, the ISAPI listener provides the best performance and is the better choice when building production grade SOAP servers using the toolkit. When ISAPI listener is chosen, the SOAP requests are posted to .wsdl file, on which the ISAPI listener (soapisap.dll) listens to and processes the incoming SOAP requests.
  3. Creates the WSML (Web Services Meta Language) file. WSML is Microsoft-specific file and is only used while working with the Microsoft SOAP Toolkit. The WSML file defines the mapping of Web service methods with the methods in the COM objects. Like WSDL, it also uses the XML syntax.

 

Let's now first build a COM object DLL and then we'll enable this COM DLL as a Web service using the SOAP Toolkit.

 

The COM DLL that we'll build here contains one method named "GetAddress" that uses the NetBIOS API call to get the network adapter addresses and returns that to the caller. See Microsoft KB article HOWTO: Get Network Adapter Address from Visual Basic (Q175472) for more information on this.

 

Start Microsoft Visual Basic 6.0, create a new ActiveX DLL project. Rename the project to NetAdapterAddr and Class1 to clsDetails. Copy the first part (step 3) code from the above KB article (Q175472) at the beginning of the clsDetails class. Add a new function (Tools | Add Procedure) and name it GetAddress. Copy the second part (step 4) code from the above KB article under the GetAddress function. Make two small changes: first change Exit Sub to Exit Function; and second instead of MsgBox, assign the network address value to the function name (GetAddress), so that the network adapter address is returned as the function return value. Build the DLL (NetAdapterAddr.dll). As an optional step, quickly write a COM client for this DLL to make sure the GetAddress method is working. Let's now enable this COM DLL as a Web service using the SOAP Toolkit.

 

The first step in creating a SOAP server using the Wizard is to create a physical directory and then create an IIS virtual directory that maps to this newly created directory. So go ahead and create a folder name TestSOAP somewhere on the hard drive and map a new IIS virtual name (also named TestSOAP) to this folder.

 

Click Start | Programs | Microsoft SOAP Toolkit | WSDL Generator, which brings up a screen as shown below:

 

Click on Next button, and in the following screen provide the name of the Web service (NetAdapterAddress) and the path where the COM DLL resides:

 

 

After clicking Next, the following screen allows you to select the classes and methods that you wish to "Web-service enable":

 

 

Check the clsDetails class and click on Next button. The following screen is the place where you decide if you wish the ASP SOAP listener or ISAPI listener. For simplicity, we'll choose the ASP listener type. This screen also allows you to choose XSD schema namespace that would be used in the request and response payloads.

 

Provide the virtual directory name that you created earlier (TestSOAP), select ASP listener type and 2001 Schema Namespace and then click on the Next button. In the next screen, keep the default encoding type (UTF-8) and change the path where you want the Wizard to create WSDL, WSML and ASP files:

 

 

This is the final screen, when you click next on this screen, the wizard looks at the COM DLL, creates WSDL, WSML and ASP file and saves them into the specified folder.

 

 

Our SOAP server is ready. The NetAdapterAddress COM DLL is now a Web service. If you browse to the generated WSDL file (http://localhost/TestSOAP/NetAdapterAddress.WSDL) you'll notice that the service port points to the generated ASP page and the Web service exposes one method named GetAddress that does not take any parameters and returns a string value:

 

 

Let's build a SOAP client for the above service.

 

Start Visual Basic 6, create a new standard EXE project, add reference to Microsoft SOAP Type Library, double click on the form and write the following code in the Form_Load method:

 

Dim objSOAPClient As New SoapClient

objSOAPClient.mssoapinit _

                  "http://localhost/TestSOAP/NetAdapterAddress.WSDL"

 

MsgBox objSOAPClient.GetAddress()

 

Set objSOAPClient = Nothing

 

By now it should be clear as to what we are doing above. The mssoapinit call initializes the SoapClient object and then we call the Web service method (GetAddress) directly using the SoapClient object.

 

As an exercise, spend some time reviewing the generated ASP page (NetAdapterAddress.asp) and see how it makes use of the SOAP Toolkit (MSSOAP.SoapServer class) to accept the request, call the respective COM method, build and serialize the response.

Using MSXML 4.0 to Call Web Services

We saw how the SOAP toolkit hides the details from us and provides the simple high-level API and wizards to write SOAP client and server applications. It also provides the low-level API that provides the maximum flexibility and control over the SOAP messaging, but requires more code. Check SOAP Toolkit documentation for more information on the low-level API.

 

It is also possible to use MSXML 4.0 as a Web service client (or server). But this surely evolves a lot of work as you'll have to do all the work of packaging and un-packaging the SOAP request/response messages. MSXML 4.0 supports the IXMLHTTPRequest interface that you can use to send HTTP requests and get the response. Check out perfectxml.com MSXML Focus section for more help on XMLHTTP and ServerXMLHTTP, the built-in classes that implement the IXMLHTTPRequest interface.

 

The benefit of creating Web services using ASP.NET is that apart from using SOAP, these Web services can also be accessed by sending just the GET or POST HTTP requests (without actually sending the SOAP request payload). If you don't want to use the SOAP Toolkit, you can use MSXML 4.0 to send a GET/POST request to a Web service method and get the response. Let's take a look at an example of this.

 

In this example, we'll send a GET request to the NewsNArticles Web service available at http://www.PerfectXML.net/WebServices/NewsNArticles/Updates.asmx. We'll use ServerXMLHTTP40 to send the GET request, if it succeeds we'll use the XPath expressions and MSXML selectNodes and selectSingleNode methods to access the returned XML data. Save the following code as PXMLNews.asp under some IIS virtual directory and browse to the page to see the latest XML News powered by the PerfectXML NewsNArticles Web service!

 

<%

Option Explicit

Dim objSXH3

Dim NewsItemNodes

Dim ItemNode

 

Set objSXH3 = Server.CreateObject("Msxml2.ServerXMLHTTP.4.0")

             

objSXH3.open _

       "GET", _

       "http://www.PerfectXML.net/WebServices/NewsNArticles/Updates.asmx/GetNews", _

       False

      

objSXH3.send

 

If objSXH3.status = 200 Then

 

       Set NewsItemNodes = objSXH3.responseXML.selectNodes("//NewDataSet/Table")

 

       For Each ItemNode In NewsItemNodes

 

              Response.Write ("<a class=defaultitem_link href=" & _

               ItemNode.selectSingleNode("Link").nodeTypedValue & _

              " target=parent>" & ItemNode.selectSingleNode("Title").nodeTypedValue & _

               "</a> &nbsp;&nbsp;<font color=gray>(" & _

               ItemNode.selectSingleNode("NewsDate").nodeTypedValue & ")</font><br>")

 

              Response.Write (ItemNode.selectSingleNode("Description").nodeTypedValue)

 

              Response.Write ("<br><hr size='1' color='#999999' width='99%' " & _

                                                                align='left' ><br>")

       Next

End If

 

Set objSXH3 = Nothing

%>

 

Instead of using Response.Write, if you wish, you can also write an XSLT transformation that converts the returned XML data into HTML.

 

Summary

The main aim of this article was to give you, the Visual Basic programmers, a brief introduction to SOAP and Web services. We saw how SOAP toolkit can be used to easily create the SOAP client and server applications in Visual Basic. At the end, we learned about using MSXML to quickly build a Web service client. We hope you enjoyed this article and also learned something new. There is a lot more to learn in the SOAP and Web services world, be sure to check out links and resources at the bottom of this article for some more references.

 

Do not hesitate to send an email to mailto:comments@perfectxml.com and ask any questions that you might have and we (perfectxml.com Team) would be very happy to provide answers to them.

Links and Resources

-         perfectxml.com SOAP Focus section (http://www.perfectxml.com/soap.asp)

 

-         perfectxml.com Web services Focus Section (http://www.perfectxml.com/WebSvc1.asp)

 

-         W3C Links

-          http://www.w3.org/2002/ws/

-          http://www.w3.org/TR/SOAP

-          http://www.w3.org/TR/soap12-part0/

-          http://www.w3.org/TR/soap12-part1/

-          http://www.w3.org/TR/soap12-part2/

-          http://www.w3.org/TR/SOAP-attachments

-          http://www.w3.org/TR/SOAP-dsig/

 

-          Microsoft Links

o        http://msdn.microsoft.com/soap

o        Microsoft SOAP Toolkit Knowledgebase articles

 

-          SOAP Discussions

o        http://discuss.develop.com/soap.html

o        http://groups.yahoo.com/group/soapbuilders/

o        http://groups.yahoo.com/group/soaplite

o        http://msdn.microsoft.com/newsgroups/loadframes.asp?ICP=msdn&sLCID=us&NewsGroup=microsoft.public.xml.soap

o        http://msdn.microsoft.com/newsgroups/loadframes.asp?ICP=msdn&sLCID=us&NewsGroup=microsoft.public.xml.soapsdk

o        http://p2p.wrox.com/list.asp?list=xml_web_services

 

  

Back to Articles Page      

  Contact Us | E-mail Us | Site Guide | About PerfectXML | Advertise ©2004 perfectxml.com. All rights reserved. | Privacy