Simple SOAP Exchange in ASP.NET

**UPDATE 7/22/2010** – So I learned that it is NOT a good idea to use MSXML in ASP.NET applications and it can create a bunch of errors, so the orginal code at the bottom is now crap, but I will keep it up, just for reference. What I did is go through my site and utilize the HttpWebRequest/HttpWebResponse method for communicating with the web service – much more efficient. Below is a code sample for ASP.NET 1.1 for sending the initial request/response to get the token, which can then be used to additional requests for more info:

<%@ Page Language="VB" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.Xml" %>
<script runat="server" language="VB">

Sub Page_Load(sender As Object, e As EventArgs)

'------------------------------------------------------------------------------------------------------
'setting up variables
'-----------------------------------------------------------------------------------------------------
Dim avuser, avpassword As String
avuser = "yourwebserviceusername"
avpassword = "yourwebservicepassword"

Dim url As String = "http://yourwebserviceurl"
Dim therequest As HttpWebRequest = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)


'----------------------------------------------------------------------------
'creating the XML string
'----------------------------------------------------------------------------

Dim strSoap As String

	strSoap = "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf
	strSoap = strSoap & "<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" "
	strSoap = strSoap & "	xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" "
	strSoap = strSoap & "	xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">" & vbCrLf
	strSoap = strSoap & "  <soap:Body>" & vbCrLf
	strSoap = strSoap & "    <Authenticate xmlns=""http://www.avectra.com/2005/"">" & vbCrLf
	strSoap = strSoap & "      <userName>" & avuser & "</userName>" & vbCrLf
	strSoap = strSoap & "      <password>"& avpassword & "</password>" & vbCrLf
	strSoap = strSoap & "    </Authenticate>" & vbCrLf
	strSoap = strSoap & "  </soap:Body>" & vbCrLf
	strSoap = strSoap & "</soap:Envelope>" & vbCrLf


'----------------------------------------------------------------------------
'Sending the request
'----------------------------------------------------------------------------

Dim encoding As New ASCIIEncoding()

Dim bytesToWrite As Byte() = encoding.GetBytes(strSoap)

therequest.Method = "POST"
therequest.ContentLength = bytesToWrite.Length
therequest.Headers.Add("SOAPAction: ""http://www.avectra.com/2005/Authenticate""")
therequest.ContentType = "text/xml; charset=utf-8"

Dim newStream As Stream = therequest.GetRequestStream()
newStream.Write(bytesToWrite, 0, bytesToWrite.Length)
newStream.Close()

'----------------------------------------------------------------------------
'Catching the response
'----------------------------------------------------------------------------

Dim theresponse As HttpWebResponse = DirectCast(therequest.GetResponse(), HttpWebResponse)
Dim dataStream As Stream = theresponse.GetResponseStream()
Dim reader As New StreamReader(dataStream)

Dim responseFromServer As String = reader.ReadToEnd()

theresponse.Close()
dataStream.Close()
reader.Close()


'----------------------------------------------------------------------------
'Turn the response into an XML document and parse it
'----------------------------------------------------------------------------

Dim XMLDocument = New XmlDocument
XMLDocument.LoadXML(responseFromServer)

Dim authXML As XmlNodeList
Dim authNode As XmlNode
Dim getToken As XmlNode
authXML = XMLDocument.GetElementsByTagName("AuthorizationToken")

Dim avtoken As String

  For Each authNode In authXML
    getToken = authNode.FirstChild
    avtoken = getToken.InnerText
  Next
'--------------------------------------------------------------------------------------
'sending the next call to get the customer key
'--------------------------------------------------------------------------------------
'here you would enter the code for the next call (with the token) to get the additional info.
'and so on and so forth...........

</script>

******THIS IS THE OLD POST AND IS ONLY KEPT FOR INFORMATIONAL PURPOSES – DO NOT USE THE CODE BELOW IN AN ASP.NET SITE****** I am very new to SOAP and the whole web services stuff, but I needed to develop an application that would grab some info from our database and manipulate it. We run an ASP.NET site and use Avectra netFORUM for our database and although the Avectra wiki had some nice examples, I wanted to do it from a simple aspx page. However, although there is tons of info out there on web services and how to consume them in ASP.NET, I could not find any that were simple enough for what I needed. I just wanted to run the exchange from a simple page, rather than compiling the whole website. I was able to convert the asp example from the wiki to aspx and I thought I would share. The methods for your web services will differ, but you ought to be able to get the gist. For those that are new (as I am), basically you just send a SOAP call as XML to the service to get a token, capture the token in a variable, and then send it back, along with the method you want to invoke and it will return the information requested. Check it:

<%@ Page Language="VB" %>
<script runat=server language=VB>
'~~~~~~~~~~~SOAP app by Hal Nesbitt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'This app grabs a member number and then returns basic information about that person from the database

Sub Page_Load


'----------------------------------------------------------------------------------------
'Define your database/web services variables
Const avURL As String = "http://yourwebservicesurl.asmx"

Dim user As String
Dim password As String
Dim host As String
Dim authenticate As String
Dim action As String
user = "yourusername"
password = "yourpassword"
host = "yourhosturl"
authenticate = "yourauthenticateaction"
action = "yourwebserviceaction"

'-----------------------------------------------------------------------------------------

'This is the membernumber of the person you are trying to lookup. It is passed in a querystring
Dim membernumber As String
membernumber = Request.QueryString("membernumber")


'Setting initial variables
Dim xmlhttp As Object 
Dim strSoap As String 
Dim xmlFile As Object 
Dim str As String 
Dim strResponse As String
Dim xmlDoc As Object
Dim oNode As String
Dim xmloutput As String
Dim token As String
Dim ASNID As String
Dim ASNPage As String

'This creates the xml that will be sent as a soap call to get the initial token

	strSoap = "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf
	strSoap = strSoap & "<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" "
	strSoap = strSoap & "	xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" "
	strSoap = strSoap & "	xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">" & vbCrLf
	strSoap = strSoap & "  <soap:Body>" & vbCrLf
	strSoap = strSoap & "    <Authenticate xmlns=""http://www.avectra.com/2005/"">" & vbCrLf
	strSoap = strSoap & "      <userName>" & user & "</userName>" & vbCrLf
	strSoap = strSoap & "      <password>"& password & "</password>" & vbCrLf
	strSoap = strSoap & "    </Authenticate>" & vbCrLf
	strSoap = strSoap & "  </soap:Body>" & vbCrLf
	strSoap = strSoap & "</soap:Envelope>" & vbCrLf

' uses "Msxml2.ServerXMLHTTP" to allow the sending of the credentials 
' which "Msxml2.XMLHTTP" won't do without a lot of screwing around 
xmlhttp = CreateObject("Msxml2.ServerXMLHTTP") 
xmlhttp.open("POST", avURL, false) 
xmlhttp.setRequestHeader ("Host", host)
xmlhttp.setRequestHeader ("Content-type", "text/xml; charset=utf-8")
xmlhttp.setRequestHeader ("Content-Length", len (strSoap)+1)
xmlhttp.setRequestHeader ("SOAPAction", authenticate)

' send the request to the web service 
xmlhttp.send(strSoap) 

'Show what SOAP I am sending. Use this for debugging
'Response.Write(strSoap)

' capture the SOAP response
	strResponse = xmlhttp.responseText
 
	' load response into xml DOM object
	xmlDoc = Server.CreateObject("Microsoft.XMLDOM")
	xmlDoc.async="false"
	xmlDoc.loadXML(strResponse)


 
	' get token if one was returned
	oNode = xmlDoc.selectSingleNode("soap:Envelope/soap:Header/AuthorizationToken/Token").Text
	If Not oNode Is Nothing Then token = xmlDoc.selectSingleNode("soap:Envelope/soap:Header/AuthorizationToken/Token").Text
	 



'Shows the SOAP Response. Use this for debugging
'Response.Write(strResponse)


'Now we have the Authorization token. Below gives the status

' check the status the web service returned 
If xmlhttp.status = "200" Then 
' we're good to go 
Response.Write("Good to go. Status is ")
Response.Write(xmlhttp.status & "<br />")
Response.Write("Authorization Token: " & avtoken)
Else 
' there's a problem 
Response.Write("shit ain't no good")
Response.Write(xmlhttp.status)
End If 

'-------------------------------------------------------------------------------

'Now we take the token and send it back to the web service to get some customer info from the supplied membernumber
'This uses the WEBWebUserGetByRecno_Custom Web Service
' concatenate xml string
strSoap = "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf
strSoap = strSoap & "<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:ns=""http://www.avectra.com/2005/"">" & vbCrLf
strSoap = strSoap & "   <soapenv:Header>" & vbCrLf
strSoap = strSoap & "      <ns:AuthorizationToken>" & vbCrLf
strSoap = strSoap & "         <ns:Token>" & token & "</ns:Token>" & vbCrLf
strSoap = strSoap & "      </ns:AuthorizationToken>" & vbCrLf
strSoap = strSoap & "   </soapenv:Header>" & vbCrLf
strSoap = strSoap & "   <soapenv:Body>" & vbCrLf
strSoap = strSoap & "      <ns:WEBWebUserGetByRecno_Custom>" & vbCrLf
strSoap = strSoap & "         <ns:cst_recno>" & membernumber & "</ns:cst_recno>" & vbCrLf
strSoap = strSoap & "      </ns:WEBWebUserGetByRecno_Custom>" & vbCrLf
strSoap = strSoap & "   </soapenv:Body>" & vbCrLf
strSoap = strSoap & "</soapenv:Envelope>" & vbCrLf


xmlhttp = CreateObject("Msxml2.ServerXMLHTTP") 
xmlhttp.open("POST", avURL, false) 
xmlhttp.setRequestHeader ("Host", host)
xmlhttp.setRequestHeader ("Content-type", "text/xml; charset=utf-8")
xmlhttp.setRequestHeader ("Content-Length", len (strSoap)+1)
xmlhttp.setRequestHeader ("SOAPAction", action)

' send the request to the web service 
xmlhttp.send(strSoap) 

'Show what SOAP I am sending. Use this for debugging
'Response.Write(strSoap)

' capture response
	strResponse = xmlhttp.responseText
 
	' load response into xml DOM object
	xmlDoc = Server.CreateObject("Microsoft.XMLDOM")
	xmlDoc.async="false"
	xmlDoc.loadXML(strResponse)

 
	' get token if one was returned. This is now the new token, in case I want to make subsequent calls to the web service
	oNode = xmlDoc.selectSingleNode("soap:Envelope/soap:Header/AuthorizationToken/Token").Text
	If Not oNode Is Nothing Then token = xmlDoc.selectSingleNode("soap:Envelope/soap:Header/AuthorizationToken/Token").Text
	 



'Shows the SOAP Response. Use this for debugging
Response.Write("<br><br>This is the XML output: <br />" & strResponse)

'Displays the new token, for subsequent calls
Response.Write("<br><br>This is the NEW token: <br />" & avtoken)


End Sub

'-----------------------------------------------------------------------------------

'This handles errors. If a membernumber is invalid, then it will redirect to an error page.

Private Sub Page_Error(ByVal sender As Object, ByVal e As System.EventArgs)
Dim errorpage As String

Response.Redirect("http://yoursite/error.aspx")
    
End Sub

</script>

Published by

Hal

Aside from being a champion yo-yoer, I am the full-time computer geek at the American Society of Nephrology. I recently completed my MBA from George Washington University which I am hoping will enable me to finally afford my own bad habits. I also do freelance design, specializing in Flash, PHP, and ASP/ASP.NET.

Leave a Reply

Your email address will not be published.