How To Send Soap Call Using Msxml Replace Stk
- 14 Jun 2007
I know… This is a simple thing, but there is no documentation on it so here it is:
UPDATE: You can now use Windows Webservica API (WWSAPI) to create native code WebService calls!
The SoapToolkit (STK) is out of support. So what if you need to make a SOAP call in VB 6 or scripting? Realizing that SOAP calls to web service are just a POST with some XML, you should be able to do this easily. You can get the format for this POST from a network sniffer such as Network Monitor (available from Microsoft) or from the WSDL of service definition.
Here is a simple definition of a web service that returns the length of a string:
GetStringLength
Test
The test form is only available for requests from the local machine.
SOAP 1.1
The following is a sample SOAP 1.1 request and response. The placeholders shown need to be replaced with actual values.
POST /HelloWS/service.asmx HTTP/1.1 Host: jsandersvm2003 Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://tempuri.org/GetStringLength" <?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> <GetStringLength xmlns="http://tempuri.org/"> <theString>string</theString> </GetStringLength> </soap:Body> </soap:Envelope>
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> <GetStringLengthResponse xmlns="http://tempuri.org/"> <GetStringLengthResult>int</GetStringLengthResult> </GetStringLengthResponse> </soap:Body> </soap:Envelope>
Here is one way to make this call in a simple VB form application. Reference MSXML3.0 in your project (beware of lines wrapping in your browser if you are a cut and past programmer).
</p>
Sub
</font></span>
</span>
Command2_Click()
‘SOAPAction: “http://tempuri.org/GetStringLength”
</p>
</font></span>
</span>
‘
‘</soap:Envelope>
</p>
</font></span>
</span>
Dim myXML As New
XMLHTTP30</p>
</font></span>
</span>
‘ False means Synchronously
</p>
</font></span>
</span>
‘myXML.send theTxt
‘ NOTE: This allows you to leverage the XML DOM
</p>
</font></span>
</span>
Dim node
“myXML.send “ ” & xmlSrcDoc.xml
</p>
</font></span>
</span>
MsgBox(xmlDoc.Text)</p>
</font></span>
</span>
‘ or this if you want to traverse the XML DOM
‘End If
</p>
End
</font></span>
</span>
Sub
‘How to send this using MSXML
‘POST /HelloWS/service.asmx HTTP/1.1
‘Host: jsandersvm2003
‘Content-Type: text/xml; charset=utf-8
‘Content -length: <
</span>
</p>
‘<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/”>
‘
</span>‘ <GetStringLength xmlns=”http://tempuri.org/”>
‘
</span>‘ </GetStringLength>
‘ </soap:Body>
</p>
myXML.open(“POST”, “http://jsandersvm2003/HelloWS/service.asmx”, False)
myXML.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”)
myXML.setRequestHeader(“SOAPAction:”, http://tempuri.org/GetStringLength)
‘ NOTE: You could do this… very brute force way to send it.
‘Dim theTxt As String
‘theTxt = “<soap:Envelope xmlns:xsi=” & Chr(34) & “http://www.w3.org/2001/XMLSchema-instance” & Chr(34) & ” xmlns:xsd=” & Chr(34) & “http://www.w3.org/2001/XMLSchema” & Chr(34) & ” xmlns:soap=” & Chr(34) & “http://schemas.xmlsoap.org/soap/envelope/” & Chr(34) & “>
Dim xmlSrcDoc As New MSXML2.DOMDocument30
xmlSrcDoc.async = False
xmlSrcDoc.validateOnParse = False
xmlSrcDoc.resolveExternals = False
xmlSrcDoc.preserveWhiteSpace = True
‘ caveat for the createProcessingInstruction. the encoding string will be missing from the XML instruction line.
‘ so you could skip the createProcessingInstruction code, instead prepend the string to the XML you generate for the rest of the body ala
‘
‘ most servers will not care about that because the HTTP header already specifies the encoding
‘ Create a processing instruction targeted for xml.
node = xmlSrcDoc.createProcessingInstruction(“xml”, “version=’1.0′”)
‘ issue: cannot do this: node.setAttribute “encoding”, “utf-8”
xmlSrcDoc.appendChild(node)
node = Nothing
‘ Create the Soap Envelope
Dim soapEnvelope As IXMLDOMElement
soapEnvelope = xmlSrcDoc.createElement(“soap:Envelope”)
‘ Create the attributes for it
soapEnvelope.setAttribute(“xmlns:soap”, “http://schemas.xmlsoap.org/soap/envelope/”)
soapEnvelope.setAttribute(“xmlns:xsi”, “http://www.w3.org/2001/XMLSchema-instance”)
soapEnvelope.setAttribute(“xmlns:xsd”, “http://www.w3.org/2001/XMLSchema”)
xmlSrcDoc.appendChild(soapEnvelope)
‘ Create the Soap Body
Dim soapBody As IXMLDOMElement
soapBody = xmlSrcDoc.createElement(“soap:Body”)
soapEnvelope.appendChild(soapBody)
‘ Create the node for the call we are making
Dim soapCall As IXMLDOMElement
soapCall = xmlSrcDoc.createElement(“GetStringLength”)
soapCall.setAttribute(“xmlns”, “http://tempuri.org/”)
soapBody.appendChild(soapCall)
‘ finally add the argument(s)
Dim soapArgs As Object
soapArgs = xmlSrcDoc.createElement(“theString”)
soapArgs.Text = “Jeff is cool”
soapCall.appendChild(soapArgs)
‘ let it go!
myXML.send(xmlSrcDoc.xml)
‘ myXML.send “ ” & xmlSrcDoc.xml
Dim xmlDoc As MSXML2.DOMDocument30
xmlDoc = myXML.responseXML
‘ This query will depend on what you expect back from the SOAP call
‘Dim oNode As Object
‘Set oNode = xmlDoc.documentElement.selectSingleNode(“//HelloWorldResult”)
‘If oNode Is Nothing Then
‘ MsgBox “Requested information not found.”
‘Else
‘ MsgBox oNode.Text