
n the article, we will create a simple SOAP service, and a client to access that
service. The service will be in the form of an Active Server Page, which I have
called
soap.aspit will need to live in the root directory of your Personal Web Service
(by default
c:\inetpub\wwwroot\) Our service will accept and process SOAP
requests made by our clienta VB exe, with a single module, and a start-up
Sub
Main().
As we know, SOAP is a call-response
mechanism, which operates in a client-server paradigm. The client (your
application) makes a call to the server (a web server, somewhere on the
internet), 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 servera caller
and a responder.
The example we will follow is a very
simple one: we will build a service that will calculate the tax due on a sales
transaction. In traditional VB terms well will create a function with the
following definition:
Public Function GetSalesTax(ByVal pSalesTotal As Double) as Double
GetSalesTax = pSalesTotal * 0.04
End Function
Crude, but effective (if you live in a
state where the sales tax rate is 4%!)
This function defines a method name
(GetSalesTax), a parameter (pSalesTotalrepresenting the total value of the
sale) and a return value (the result of the function). In more traditional
object-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 IN
and OUT parametersthe client passes IN parameters to the server,
and then receives the OUT parameters in return. So, in order to create our
SOAP service, we need a server that will listen for requests to GetSalesTax,
accompanied by IN parameters, and which will respond with OUT
parameters, 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 to
the GetSalesTax function described above, would be something such as:
dblSalesTax = GetSalesTax(100)
Returning a value of $4.
If the GetSalesTax function was contained
within an external object, such as an MTS server, then the call would need to
reference the server DLL:
Dim objTax As New CTaxCalc
dblSalesTax = objTax.GetSalesTax(100)
In a SOAP system the call is little
different, only the request is formatted as an XML document, which is passed up
to the server. The appropriate document contains the same details as the MTS
calla method to call, and the parameter name and value.
<GetSalesTax>
<SalesTotal>100</SalesTotal>
<GetSalesTax>
In order to ensure that the server can
correctly identify and decrypt this method call, it is wrapped up in a larger
document, called a SOAP envelope, which references the universal name-space of
the SOAP envelope standard.
<SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
<SOAP:Header></SOAP:Header>
<SOAP:Body>
<GetSalesTax>
<SalesTotal>100</SalesTotal>
<GetSalesTax>
</SOAP:Body>
</SOAP:Envelope>
Finally, to complete our SOAP request
document, we will add a name-space reference to our method call, which points to
the object which contains the methodthe equivalent of the object declaration
(Dim objTax As New CTaxCalc) in our MTS method call.
<SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
<SOAP:Header></SOAP:Header>
<SOAP:Body>
<m:GetSalesTax xmlns:m="urn:myserver/soap:TaxCalc">
<SalesTotal>100</SalesTotal>
</m:GetSalesTax>
</SOAP:Body>
</SOAP:Envelope>
Now that we have built our SOAP request document, we are
ready to send it to the server. The request is a simple HTTP postjust like
posting a web form in your internet browser. Of course, your internet browser
masks 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 do
the job ourselves; and I have been using Microsoft’s XML HTTP Request object
to give me a helping hand. (The XMLHTTPRequest is an object within the MSXML
class library (MSXML.DLL), and it comes with IE5.) Assuming that strEnvelope
contains the XML document described above, the request is formatted thus:
Dim objHTTP As New MSXML.XMLHTTPRequest
Dim strEnvelope As String
'Set up to post to our localhost server
objHTTP.open "post", "http://localhost/soap/soap.asp"
'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:TaxCalc#GetSalesTax"
'Make the SOAP call
objHTTP.send strEnvelope
'Get the return value
strReturn = 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 post
sent by the client. It will be noted that we direct the client’s post to a URL
on our local serverhttp://localhost/soap.asp. So our first job is to create
this page, to listen for, and process, SOAP calls to our server. We know that
our ASP will receive an XML document, in the form of an HTTP post, with a method
name (GetSalesTax), and a parameter (SalesTotal). So, to write our basic
listener service, all we need do is deconstruct the body of the request (the
SOAP envelope) and pull out the value of the SalesTotal parameter.
The SOAP envelope posted by the client is contained in the
body 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.asp
begins like this:
Set objReq = Server.CreateObject("Microsoft.XMLDOM")
objReq.Load Request
Thus objReq contains the SOAP envelope we created on the
client, and we can extract the value of the SalesTotal parameter by running an
XSL 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 calculation
to get the sales-tax:
varSalesTax = varSalesTotal * 0.04