Simple Object Access Protocol: A Step-By-Step Approach

Simple Object Access Protocol: A Step-By-Step Approach

n the article, we will create a simple SOAP service, and a client to access thatservice. The service will be in the form of an Active Server Page, which I havecalled soap.asp?it will need to live in the root directory of your Personal Web Service(by default c:inetpubwwwroot) Our service will accept and process SOAPrequests made by our client?a VB exe, with a single module, and a start-up SubMain().

As we know, SOAP is a call-responsemechanism, which operates in a client-server paradigm. The client (yourapplication) makes a call to the server (a web server, somewhere on theinternet), passing in parameters; and the server provides a response.Both call and response are transported in the form of XML documents. Therefore,to build our own example SOAP system, we need both a client and a server?a callerand a responder.

The example we will follow is a verysimple one: we will build a service that will calculate the tax due on a salestransaction. In traditional VB terms well will create a function with thefollowing definition:

Public Function GetSalesTax(ByVal pSalesTotal As Double) as Double  GetSalesTax = pSalesTotal * 0.04End Function

Crude, but effective (if you live in astate where the sales tax rate is 4%!)

This function defines a method name(GetSalesTax), a parameter (pSalesTotal?representing the total value of thesale) and a return value (the result of the function). In more traditionalobject-oriented terms, we might think of pSalesTotal as an IN parameter,and the GetSalesTax result as an OUT parameter. Quite straightforwardly:sales-total in; sales-tax out. A SOAP service can be thought of in terms of INand OUT parameters?the client passes IN parameters to the server,and then receives the OUT parameters in return. So, in order to create ourSOAP service, we need a server that will listen for requests to GetSalesTax,accompanied by IN parameters, and which will respond with OUTparameters, indicating the correct tax amount. Let’s start with the client?the caller. How do we call the SOAP service to make our request.

The Client
In traditional VB terms, our request tothe GetSalesTax function described above, would be something such as:

dblSalesTax = GetSalesTax(100)

Returning a value of $4.

If the GetSalesTax function was containedwithin an external object, such as an MTS server, then the call would need toreference the server DLL:

Dim objTax As New CTaxCalcdblSalesTax = objTax.GetSalesTax(100)

In a SOAP system the call is littledifferent, only the request is formatted as an XML document, which is passed upto the server. The appropriate document contains the same details as the MTScall?a method to call, and the parameter name and value.


In order to ensure that the server cancorrectly identify and decrypt this method call, it is wrapped up in a largerdocument, called a SOAP envelope, which references the universal name-space ofthe SOAP envelope standard.


Finally, to complete our SOAP requestdocument, we will add a name-space reference to our method call, which points tothe object which contains the method?the equivalent of the object declaration(Dim objTax As New CTaxCalc) in our MTS method call.


Now that we have built our SOAP request document, we areready to send it to the server. The request is a simple HTTP post?just likeposting a web form in your internet browser. Of course, your internet browsermasks all the complexity of sending a form to a server; and in the longer-term.NET will mask this process from your VB code too. But for now, we need to dothe job ourselves; and I have been using Microsoft’s XML HTTP Request objectto give me a helping hand. (The XMLHTTPRequest is an object within the MSXMLclass library (MSXML.DLL), and it comes with IE5.) Assuming that strEnvelopecontains the XML document described above, the request is formatted thus:

Dim objHTTP As New MSXML.XMLHTTPRequestDim strEnvelope As String'Set up to post to our localhost "post", "http://localhost/soap/soap.asp"'Set a standard SOAP/ XML header for the content-typeobjHTTP.setRequestHeader "Content-Type", "text/xml"'Set a header for the method to be calledobjHTTP.setRequestHeader "SOAPMethodName", _    "urn:myserver/soap:TaxCalc#GetSalesTax"'Make the SOAP callobjHTTP.send strEnvelope'Get the return valuestrReturn = objHTTP.responseBody

Now that we have sent our request, we move to the server,to see how we set up a SOAP service to listen and respond to our calls.

The Server
Our server needs to be configured to accept the HTTP postsent by the client. It will be noted that we direct the client’s post to a URLon our local server?http://localhost/soap.asp. So our first job is to createthis page, to listen for, and process, SOAP calls to our server. We know thatour ASP will receive an XML document, in the form of an HTTP post, with a methodname (GetSalesTax), and a parameter (SalesTotal). So, to write our basiclistener service, all we need do is deconstruct the body of the request (theSOAP envelope) and pull out the value of the SalesTotal parameter.

The SOAP envelope posted by the client is contained in thebody of the request, or in ASP terms the Request object; and because it is XML,we can load it into an instance of Microsoft’s XMLDOM in our ASP. Soap.aspbegins like this:

Set objReq = Server.CreateObject("Microsoft.XMLDOM")objReq.Load Request

Thus objReq contains the SOAP envelope we created on theclient, and we can extract the value of the SalesTotal parameter by running anXSL pattern query, using the SelectSingleNode method of the XML DOM object :

strQuery = "SOAP:Envelope/SOAP:Body/m:GetSalesTax/SalesTotal" varSalesTotal = objReq.SelectSingleNode(strQuery).Text

With the parameter extracted, we can make our calculationto get the sales-tax:

varSalesTax = varSalesTotal * 0.04

Return the Value
Now we have the return value for sales-tax?the response?ready to pass back to the client, but as with the request, we need to formatthis response correctly, in order to comply with the SOAP standard. The SOAPresponse envelope conforms to a format-type identical to the request. The onlydifference is that the “IN” parameter (SalesTotal, in our case) is replacedby an OUT parameter?SalesTax, and the method name indicates that thedocument is a response:


We can build up this document, either bystring-concatenation, or by creating a new instance of a DOM, and appending theappropriate nodes.

Back on the client, the response is received, and can bedecoded by extracting the appropriate node from the Envelope document:

Dim objReturn As New MSXML.DomDocumentobjReturn.LoadXML strReturnstrQuery = "SOAP:Envelope/SOAP:Body/m:GetSalesTaxResponse/SalesTax"dblTax = objReturn.SelectSingleNode(strQuery).Text

And that’s it! A functional, compliant SOAP service in afew easy steps. Of course, the service that we have provided is far fromsophisticated, but that is to miss the point. In the not-too-distant future,Visual Studio 7 will completely mask the implementation of SOAP; but I believethat there is value in understanding the way the engine turns beneath the hood.SOAP itself is a very simple protocol; and I hope you leave this article with abetter understanding the infrastructure that lies behind SOAP, and themethodology through which SOAP-based component services are going to be providedin the future.

Appendix 1: VBClient Code

NB?This project contains a single module, with a Sub Main start-up object, and references the MSXML library. The code assumes you are running a local web server (localhost), and that soap.asp is located in the web root, as described below.

Sub Main()  Dim objHTTP As New MSXML.XMLHTTPRequest  Dim strEnvelope As String  Dim strReturn As String  Dim objReturn As New MSXML.DOMDocument  Dim dblTax As Double  Dim strQuery As String    'Create the SOAP Envelope  strEnvelope = _    "" & _    "
" & _ "" & _ "" & _ "100" & _ "" & _ "" & _ "
" 'Set up to post to our local server "post", "http://localhost/soap.asp", False 'Set a standard SOAP/ XML header for the content-type objHTTP.setRequestHeader "Content-Type", "text/xml" 'Set a header for the method to be called objHTTP.setRequestHeader "SOAPMethodName", _ "urn:myserver/soap:TaxCalculator#GetSalesTax" 'Make the SOAP call objHTTP.send strEnvelope 'Get the return envelope strReturn = objHTTP.responseText 'Load the return envelope into a DOM objReturn.loadXML strReturn 'Query the return envelope strQuery = _ "SOAP:Envelope/SOAP:Body/m:GetSalesTaxResponse/SalesTax" dblTax = objReturn.selectSingleNode(strQuery).Text Debug.Print dblTaxEnd Sub

Appendix 2:ASP Server Code

This code resides in an ASP?Soap.asp, in the rootdirectory of the web server.

" & _	"
" & _ "" & _ "" & _"" & varSalesTax & "" & _ "" & _ "" & _ ""'Write the return envelopeResponse.Write strTmp%>


Share the Post: