Consuming a WSDL Webservice from
ASP
By
Dave@123aspx.com
Click here for the live demo
(Look at the bottom of the
homepage)
Last week I exposed my site, 123aspx.com, as a SOAP
webservice. However, most webmasters feel you need to run ASP.NET or
the SOAP toolkit to take advantage this service. This isn't necesarily
true, with a little ingunetiy and the latest XML parser from Microsoft, you can
consume SOAP services from a traditional ASP page. This tutorial will show you
how.
Overview
This example application uses
the 123aspx.com webservice as an example. I'll be using the following
three files to demonstrate consuming this service from
ASP:.
global.asa -- used to populate an Application level
variable with the SOAP data when the application
starts.
i_soapcall.asp -- an include file used to call the SOAP
webservice.
default.asp -- a standard ASP page used to display the
formatted SOAP data.
Global.asa
The
global.asa file is fired everytime the website starts. Specically the
event Sub Application_OnStart is called. Inside of this sub, we are going to
populate an application level variable with our SOAP data. Lets take a look at
the code.
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
Dim ASPNETResources
ASPNETResources =
GetASPNetResources()
Application("ASPNETExpires") = 12 'set the content to
expire in 12 hours.
If Len(ASPNETResources) >0
then 'populate the application level variables
Application.Lock
Application("ASPNETResourcesUpdated")=Now()
Application("ASPNETResourceList")=ASPNETResources
Application.UnLock
End if
End Sub
</script>
<!-- #include file="i_soapcall.asp" -->
When
Application_OnStart first fires, we dimension a variable called ASPNETResources,
which is populated by a function call GetASPNetResources(),
GetASPNetResources(), found inside of the include file i_soapcall.asp, returns a
string of HTML. We will be getting to i_soapcall.asp shortly. Lets go over
some of the logic of the global.asa code. Once we have made our
function call, we are storing an an expiration time of 12 hours the variable
Application("ASPNETExpires"). We'll use this later in default.asp. We also check
to see if the function was sucessful and returned a string with a length greater
than 0. If ASPNETResources was populated, then we need to record the time
it was populated, Application("ASPNETResourcesUpdated"), and store the results
in the application level variable, Application("ASPNETResourceList").
Default.asp
The default.asp is used to
display the formatted contents of our webservice request. Let's start out
by looking at the code of default.asp.
<%
Dim ASPNETResources
If
len( Application("ASPNETResourceList") )>0 then 'we have
our latest resources
REM -- check to see if they expired
If DateDiff("h",Now(),Application("ASPNETResourcesUpdated")) >
Application("ASPNETExpires") Then
REM -- we need to update the
latest resurces
ASPNETResources
= GetASPNetResources()
Application.Lock
Application("ASPNETResourcesUpdated")=Now()
Application("ASPNETResourceList")=ASPNETResources
Application.UnLock
End if 'datediff...
Else 'for some reason the application level
variable is empty, fill it.
ASPNETResources =
GetASPNetResources()
Application.Lock
Application("ASPNETResourcesUpdated")=Now()
Application("ASPNETResourceList")=ASPNETResources
Application.UnLock
End if
Response.Write
Application("ASPNETResourceList")
%>
The first thing we
want to check is to see if our application level variable,
Application("ASPNETResourceList"), has been populated. We do that by checking
it's length:
If len(
Application("ASPNETResourceList") )>0 then 'we have our latest
resources
If indeed, there is data, we need to check to see if
the data has expired. Using the DateDiff function, we can check to see if
the data has expired past our timespan of 12 hours which was set in our
global.asa as Application("ASPNETExpires").
If
DateDiff("h",Now(),Application("ASPNETResourcesUpdated")) >
Application("ASPNETExpires") Then
If our data has
expired or, if for some reason, Application("ASPNETResourceList") is empty, we
call our soap service to populate our variable with data. We are using the same
logic that we did in the global.asa. Once we have our data, we execute a
Response.Write() to send our formatted results to the client.
Now the Good Stuff - i_soapcall.asp
Now to the heart of the matter, it's what we've all been waiting for,
how is this mysterious function GetASPNetResources(), consuming a webservice
from legacy ASP? Remeber that our SOAP service is really serving up a XML
formatted text file. If we can somehow, progromattically, get to
that XML file, then we should be able to parse it. Well in our case, it turns
out it's really not that difficult. Inside of our function, we call two
objects:
Function GetASPNetResources()
Set SoapRequest =
Server.CreateObject("MSXML2.XMLHTTP")
Set myXML
=Server.CreateObject("MSXML.DOMDocument")
SoapRequest is the
server-side component that can make POST and GET requests across the web.
For more info on the MSXML2.XMLHTTP component, you can visit MSDN.
myXML will be used to create an in-memory XML document of our SOAP
service. Now that we have our objects, let's call our SOAP service.
myXML.Async=False
SoapURL
= "http://64.85.12.73/WebSvc/whatsnew123apx_ds.asmx/GetNew123aspXResources?"
SoapRequest.Open "GET",SoapURL , False
SoapRequest.Send()
if Not myXML.load(SoapRequest.responseXML) then 'an Error
loading XML
returnString = ""
Else 'parse the XML
First we we set the Asyncronous property of our XMLDocument object
to false. This will require the entire SOAP xml document to get loaded into
memory before we continue processing code. We set SoapURL to the url
of our webservice, and then we open a connection to our webservice using:
SoapRequest.Open "GET",SoapURL , False
SoapRequest.Open takes 5 parameters. Only the first two are required and the
remaining three are optional. Here is a breakdown of the 5 parameters:
oServerXMLHTTPRequest.open bstrMethod, bstrUrl,
bAsync, bstrUser, bstrPassword
Parameters
bstrMethod
HTTP method used to open the
connection, such as PUT or PROPFIND.
bstrUrl
Requested URL. This must be
an absolute URL, such as "http://Myserver/Mypath/Myfile.asp".
bAsync
(optional)
Boolean. Indicator as to whether
the call is asynchronous. The default is False (the call does not return
immediately).
bstrUser (optional)
Name of the user for
authentication.
bstrPassword (optional)
Password for authentication.
This parameter is ignored if the user parameter is Null or missing
With our open connection, we make a request across the web by calling
SoapRequest.Send(). The webserver sends the results back, and they are stored in
the property SoapRequest.responseXML,as text. We take this text and load it
asycronously into an in-memory resident XML Dom object by calling the load
method of myXML. If any xml parsing errors occur, the document is not loaded and
we decide to return an empty string. If the XML document was loaded
successfully, we parse document and look for our data.
Parsing the XML Document
Our SOAP
service returns 4 fields: Name, URL, Domain, and DateUpdated. In this version of
calling our SOAP service, we are only going to display the Name and URL
fields. So how do we get at these fields? We search for them specifiing
the XPath syntax for searching.
REM -- The XML
Nodes are CASE SENSITIVVE!
Set
nodesURL=myXML.documentElement.selectNodes("//URL")
Set nodesName=myXML.documentElement.selectNodes("//Name")
NumOfNodes = nodesURL.Length
The "//"
characters are used to denote "find all instances of " in XPath. Therefore,
using "//URL" will return an arry of nodes in the XML document named
"URL". We have to be careful here, because XML is case sensitive, calling
"//url" will not return any nodes at all. We check the length of the array by
calling nodesURL.Length.
The Hard Part is
Over
We've called our SOAP service, and now we have
access to our nodes, all that's left is to format and display it to the HTML
client.
ResourceList = "<font face=verdana
size=2>Latest ASP.NET Resources</font><ul>"
For i = 0 to NumOfNodes
-1
ResourceList = ResourceList &
"<li><a href=" & nodesURL(i).text & "><font face=verdana
size=2>" & nodesName(i).text & "</font></a></li>"
next
ResourceList
=ResourceList & "</ul>"
returnString =
ResourceList
GetASPNetResources = returnString
Because the array of nodes is a zero based array, we run a For loop to a
maximum of NumOfNodes -1. We dynamically build a string, wrapping <li>
</li> around our Names and URLs. We could have easily have built an
HTML table or some other structure. We store our formatted HTML string in
returnString, and pass returnString back to the function call
GetASPNetResources = returnString.
A screen shot of our formatted
results.

That's All!
That's all their is to calling a SOAP service from a legacy ASP
page. We've called our SOAP service and passed it into an XML object
using Microsoft's parsers:
MSXML2.XMLHTTP and MSXML.DOMDocument. We've
looped through the collection of nodes and created an HTML formatted string.
We've simulated ASP.NET caching by storing the HTML formatted string in an
Application level varable. Here is the code in its entirety.
All the code
Global.asa
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart
Dim
ASPNETResources
ASPNETResources = GetASPNetResources()
Application("ASPNETExpires") = 12
'set the content to expire in 12 hours.
If
Len(ASPNETResources) >0 then 'populate the application
level variables
Application.Lock
Application("ASPNETResourcesUpdated")=Now()
Application("ASPNETResourceList")=ASPNETResources
Application.UnLock
End if
End Sub
</script>
<!-- #include
file="i_soapcall.asp" -->
Default.asp
<%@
Language=VBScript %>
<%Option Explicit%>
<!--
#include file="i_soapcall.asp" -->
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<%
Dim ASPNETResources
If
len( Application("ASPNETResourceList") )>0 then 'we have
our latest resources
REM -- check to see if they expired
If DateDiff("h",Now(),Application("ASPNETResourcesUpdated")) >
Application("ASPNETExpires") Then
REM -- we need to update the
latest resurces
ASPNETResources = GetASPNetResources()
Application.Lock
Application("ASPNETResourcesUpdated")=Now()
Application("ASPNETResourceList")=ASPNETResources
Application.UnLock
End if 'datediff...
Else 'for some reason the application level
variable is empty, fill it.
ASPNETResources =
GetASPNetResources()
Application.Lock
Application("ASPNETResourcesUpdated")=Now()
Application("ASPNETResourceList")=ASPNETResources
Application.UnLock
End if 'len(..
Response.Write
Application("ASPNETResourceList")
%>
<P> </P>
</BODY>
</HTML>
i_soapcall.asp
<script language="vbscript" runat="server">
Function GetASPNetResources()
Dim returnString
Dim myXML
Dim SoapRequest
Dim SoapURL
Set SoapRequest = Server.CreateObject("MSXML2.XMLHTTP")
Set myXML =Server.CreateObject("MSXML.DOMDocument")
myXML.Async=False
SoapURL =
"http://64.85.12.73/WebSvc/whatsnew123apx_ds.asmx/GetNew123aspXResources?"
SoapRequest.Open "GET",SoapURL , False
SoapRequest.Send()
if Not myXML.load(SoapRequest.responseXML) then 'an Error
loading XML
returnString = ""
Else 'parse the XML
Dim nodesURL
Dim nodesName
Dim
nodesDateUpdated
Dim
nodesDomain
Dim NumOfNodes
Dim ResourceList
Dim i
REM -- The XML Nodes are CASE SENSITIVVE!
Set
nodesURL=myXML.documentElement.selectNodes("//URL")
Set
nodesName=myXML.documentElement.selectNodes("//Name")
REM -- uncomment the following lines if we want to access the
DataUpdated and the Domain Nodes
REM --Set nodesDateUpdated =
myXML.documentElement.selectNodes("//DateUpdated")
REM --Set nodesDomain =
myXML.documentElement.selectNodes("//Domain")
REM -- the number of nodes in the list
NumOfNodes = nodesURL.Length
ResourceList = "<font
face=verdana size=2>Latest ASP.NET Resources</font><ul>"
For i = 0 to NumOfNodes -1
ResourceList = ResourceList & "<li><a href=" &
nodesURL(i).text & "><font face=verdana size=2>" &
nodesName(i).text & "</font></a></li>"
next
ResourceList =ResourceList &
"</ul>"
returnString = ResourceList
Set nodesURL =
Nothing
Set nodesName =
Nothing
End If
Set
SoapRequest = Nothing
Set myXML =
Nothing
GetASPNetResources = returnString
End Function
</script>
如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐
jill.jiang@amteam.org | 021-51096826-112 |
在线联系