Sending a 'application/soap+xml' SOAP request using Classic ASP
Categories:
Sending 'application/soap+xml' Requests with Classic ASP
Learn how to construct and send SOAP 1.2 requests using MSXML2.ServerXMLHTTP in Classic ASP, including XML payload creation and error handling.
Classic ASP, while an older technology, is still in use for many legacy systems. Interacting with modern web services, especially those using SOAP 1.2 with the application/soap+xml
content type, can be a challenge. This article will guide you through the process of creating the necessary XML payload, setting up the MSXML2.ServerXMLHTTP
object, and sending the request to a SOAP endpoint.
Understanding SOAP 1.2 and application/soap+xml
SOAP (Simple Object Access Protocol) is a messaging protocol specification for exchanging structured information in the implementation of web services. SOAP 1.2 introduced the application/soap+xml
media type, which is distinct from the older text/xml
used by SOAP 1.1. This distinction is crucial for web service compatibility.
When sending a SOAP 1.2 request, your HTTP Content-Type
header must be set to application/soap+xml
. Additionally, the XML payload itself needs to adhere to the SOAP 1.2 envelope structure, which includes namespaces for the envelope, encoding style, and potentially the body. The Action
header, which specifies the intent of the SOAP request, is also typically included.
sequenceDiagram participant Client as Classic ASP Client participant Server as SOAP Web Service Client->>Server: HTTP POST Request Note over Client,Server: Content-Type: application/soap+xml Client->>Server: SOAP 1.2 Envelope (XML Payload) Server-->>Client: HTTP 200 OK (or error) Server-->>Client: SOAP 1.2 Response (XML Payload)
Sequence diagram of a Classic ASP client sending a SOAP 1.2 request to a web service.
Constructing the SOAP 1.2 XML Payload
The core of any SOAP request is its XML payload. For SOAP 1.2, this involves a specific structure. You'll typically use the MSXML2.DOMDocument
object in Classic ASP to build this XML programmatically. This approach offers better control and avoids issues with string concatenation for complex XML.
Here's a typical structure for a SOAP 1.2 request envelope:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body>
<m:YourMethodName xmlns:m="http://your-namespace.com/your-service">
<m:Parameter1>Value1</m:Parameter1>
<m:Parameter2>Value2</m:Parameter2>
</m:YourMethodName>
</soap:Body>
</soap:Envelope>
Example SOAP 1.2 XML payload structure.
Sending the Request with MSXML2.ServerXMLHTTP
The MSXML2.ServerXMLHTTP
object is the preferred choice for making HTTP requests from Classic ASP, especially in server-side environments, as it offers better security and functionality compared to MSXML2.XMLHTTP
. You'll need to set the appropriate headers, including Content-Type
and SOAPAction
(though SOAPAction
is technically optional for SOAP 1.2, many services still expect it).
Below is a comprehensive example demonstrating how to create the XML, set headers, send the request, and process the response.
<%@ Language=VBScript %>
<% Option Explicit %>
<%
Dim objXMLDoc, objXMLHttp
Dim strURL, strSOAPAction, strRequestXML, strResponseXML
Dim strMethodNamespace, strMethodName
' --- Configuration ---
strURL = "http://your-soap-service.com/Service.asmx"
strMethodNamespace = "http://your-namespace.com/your-service"
strMethodName = "YourMethodName"
strSOAPAction = strMethodNamespace & "/" & strMethodName ' Often required, even for SOAP 1.2
' --- 1. Create the XML Payload ---
Set objXMLDoc = Server.CreateObject("MSXML2.DOMDocument.6.0")
objXMLDoc.async = False
objXMLDoc.preserveWhiteSpace = False
' Create SOAP Envelope
Dim objEnvelope, objHeader, objBody, objMethod
Set objEnvelope = objXMLDoc.createNode(1, "soap:Envelope", "http://www.w3.org/2003/05/soap-envelope")
objXMLDoc.appendChild objEnvelope
Set objHeader = objXMLDoc.createNode(1, "soap:Header", "http://www.w3.org/2003/05/soap-envelope")
objEnvelope.appendChild objHeader
Set objBody = objXMLDoc.createNode(1, "soap:Body", "http://www.w3.org/2003/05/soap-envelope")
objEnvelope.appendChild objBody
' Create Method Node
Set objMethod = objXMLDoc.createNode(1, "m:" & strMethodName, strMethodNamespace)
objBody.appendChild objMethod
' Add Parameters
Dim objParam1, objParam2
Set objParam1 = objXMLDoc.createNode(1, "m:Parameter1", strMethodNamespace)
objParam1.text = "Value1"
objMethod.appendChild objParam1
Set objParam2 = objXMLDoc.createNode(1, "m:Parameter2", strMethodNamespace)
objParam2.text = "Value2"
objMethod.appendChild objParam2
strRequestXML = objXMLDoc.xml
Response.Write "<h2>Request XML:</h2>"
Response.Write "<pre>" & Server.HTMLEncode(strRequestXML) & "</pre>"
' --- 2. Send the HTTP Request ---
Set objXMLHttp = Server.CreateObject("MSXML2.ServerXMLHTTP.6.0")
objXMLHttp.Open "POST", strURL, False ' False for synchronous call
' Set Headers
objXMLHttp.setRequestHeader "Content-Type", "application/soap+xml; charset=utf-8"
objXMLHttp.setRequestHeader "SOAPAction", strSOAPAction ' Some services still require this
' Send the request with the XML payload
objXMLHttp.send strRequestXML
' --- 3. Process the Response ---
If objXMLHttp.Status = 200 Then
strResponseXML = objXMLHttp.responseText
Response.Write "<h2>Response XML (Success):</h2>"
Response.Write "<pre>" & Server.HTMLEncode(strResponseXML) & "</pre>"
Else
Response.Write "<h2>Error:</h2>"
Response.Write "<p>Status: " & objXMLHttp.Status & " " & objXMLHttp.statusText & "</p>"
Response.Write "<p>Response Text: " & Server.HTMLEncode(objXMLHttp.responseText) & "</p>"
End If
' --- Cleanup ---
Set objXMLDoc = Nothing
Set objXMLHttp = Nothing
%>
MSXML2.DOMDocument.6.0
and MSXML2.ServerXMLHTTP.6.0
for the latest features and security. Older versions (e.g., MSXML2.XMLHTTP
) might lack certain functionalities or have security vulnerabilities.Error Handling and Response Parsing
Robust error handling is crucial when interacting with external services. The objXMLHttp.Status
property will give you the HTTP status code. A 200 OK
generally indicates a successful HTTP transaction, but the SOAP response itself might contain application-level errors within the SOAP Fault element.
To parse the response, you can load objXMLHttp.responseText
back into an MSXML2.DOMDocument
object and then use XPath or selectSingleNode
to extract specific data or check for SOAP Faults.
<%
' ... (previous code to send request and get strResponseXML) ...
If objXMLHttp.Status = 200 Then
Dim objResponseDoc, objFaultNode
Set objResponseDoc = Server.CreateObject("MSXML2.DOMDocument.6.0")
objResponseDoc.async = False
objResponseDoc.loadXML strResponseXML
' Check for SOAP Fault
objResponseDoc.setProperty "SelectionNamespaces", "xmlns:soap='http://www.w3.org/2003/05/soap-envelope'"
Set objFaultNode = objResponseDoc.selectSingleNode("//soap:Fault")
If Not objFaultNode Is Nothing Then
Response.Write "<h2>SOAP Fault Detected:</h2>"
Response.Write "<pre>" & Server.HTMLEncode(objFaultNode.xml) & "</pre>"
' Extract specific fault details if needed
' Dim objCode, objReason
' Set objCode = objFaultNode.selectSingleNode("//soap:Code/soap:Value")
' Set objReason = objFaultNode.selectSingleNode("//soap:Reason/soap:Text")
' If Not objCode Is Nothing Then Response.Write "<p>Fault Code: " & objCode.text & "</p>"
' If Not objReason Is Nothing Then Response.Write "<p>Fault Reason: " & objReason.text & "</p>"
Else
Response.Write "<h2>SOAP Response (No Fault):</h2>"
Response.Write "<pre>" & Server.HTMLEncode(strResponseXML) & "</pre>"
' Example: Extracting a value from the response
' Dim objResultNode
' objResponseDoc.setProperty "SelectionNamespaces", "xmlns:soap='http://www.w3.org/2003/05/soap-envelope' xmlns:m='http://your-namespace.com/your-service'"
' Set objResultNode = objResponseDoc.selectSingleNode("//m:YourMethodNameResponse/m:YourResultElement")
' If Not objResultNode Is Nothing Then
' Response.Write "<p>Result: " & objResultNode.text & "</p>"
' Else
' Response.Write "<p>Could not find expected result element.</p>"
' End If
End If
Set objResponseDoc = Nothing
Else
' HTTP Error already handled above
End If
' ... (cleanup) ...
%>
Example of parsing a SOAP response and checking for faults.