Search code examples
asp.netxmliismsxml6

How do I send XML from one ASP.NET page to another?


I've spent all day struggling with ASP.NET. I've made an .aspx page that sends XML to other .aspx page that reads the previous XML and sends a response to the first page.

The first page appears to work, but the second fails. I suspect it's something in environment, rather than ASP code, but I can't figure the point.

Let's expose the environments: - IIS 6.0 - ASP.NET version 2.0.50727 - Windows Server 2003 R2 SP2 Std. edition

(This has been tested in IIS 7.5, ASP.NET 2 and 4, Windows Server 2008R2, with same results)

Now, let's expose the webpages codes.

SimplePoster.aspx

<%@Page AspCompat=true Language = VB%>
<HTML>
<HEAD>
</HEAD>
<%
'Put together some XML to post off
Dim xmlString = "<?xml version=""1.0""?>" & vbcrlf
xmlString = xmlString & "<Req1>" & vbcrlf
xmlString = xmlString & " <Name>Jenny</Name>" & vbcrlf
xmlString = xmlString & "</Req1>"

'Load the XML into an XMLDOM object
Dim SendDoc = server.createobject("Microsoft.XMLDOM")
SendDoc.ValidateOnParse= True
SendDoc.LoadXML(xmlString)

'Set the URL of the receiver
Dim sURL = "http://myserver/Receiver.aspx"

'Call the XML Send function (defined below)
Dim poster = Server.CreateObject("MSXML2.ServerXMLHTTP")
poster.open("POST", sURL, false)
poster.setRequestHeader("CONTENT_TYPE", "text/xml")
poster.send(SendDoc)
Dim NewDoc = server.createobject("Microsoft.XMLDOM")
newDoc.ValidateOnParse= True
newDoc.LoadXML(poster.responseTEXT)

'We receive back another XML DOM object!

'Tell the user what happened
response.Write ("<b>XML DOC posted off:</b><br>")
response.write (SendDoc.XML & "<br>")
response.write ("<b>Target URL:</b> " & sURL & "<br>")
response.write ("<b>XML DOC Received back: </b><br>")
response.write (NewDoc.Xml)
%>
</HTML>

Receiver.aspx

<%@Page AspCompat=true Language = VB%>
<%
'Create an XML DOM Object to receive the request
'dim docReceived = CreateObject("Microsoft.XMLDOM") 'docReceived.load(request) Valid only in IIS 5.0?
dim docReceived = CreateObject("Msxml2.DOMDocument.6.0")
docReceived.async = False
docReceived.load(Request)

'Create a piece of XML to send back
Dim listItem = docReceived.selectnodes("Req1")

Dim strResponse = "<?xml version=""1.0""?>" & vbcrlf
strResponse = strResponse & "<Person>" & vbcrlf

'For the purposes of this example we modify
'the response based on the request
Dim node
Dim name
for each node in listItem
name = node.selectsinglenode("Name").firstchild.nodevalue
strResponse = strResponse & " <Name>Thanks " & name & "</Name>" & vbcrlf
next

strResponse = strResponse & "</Person>"

'Send the response back
response.write(strResponse)
%>

Now, let's open http://myserver/SimplePoster.aspx with IE. The output is:

XML DOC posted off:
Jenny 
Target URL: http://localhost/Test1/Receiver.aspx
XML DOC Received back:

Note that response is empty... now let's open http://localhost/Receiver.aspx:

Server Error in '/' Application.
--------------------------------------------------------------------------------

Value does not fall within the expected range. 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.ArgumentException: Value does not fall within the expected range.

Source Error: 


Line 5:  dim docReceived = CreateObject("Msxml2.DOMDocument.6.0")
Line 6:  docReceived.async = False
Line 7:  docReceived.load(Request)
Line 8:  
Line 9:  'Create a piece of XML to send back


Source File: C:\Inetpub\TestAxXMLInbox\Receiver.aspx    Line: 7 

Stack Trace: 


[ArgumentException: Value does not fall within the expected range.]
   Microsoft.VisualBasic.CompilerServices.LateBinding.InternalLateCall(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack, Boolean IgnoreReturn) +776
   Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateCall(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, Boolean IgnoreReturn) +367336
   ASP.test1_receiver_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) in C:\Inetpub\TestAxXMLInbox\Test1\Receiver.aspx:7
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +98
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +20
   System.Web.UI.Page.Render(HtmlTextWriter writer) +26
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +25
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +121
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +22
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2558




--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433 

Now, the million dollars question... what is raising this issue? *How can I receive XML (or text) in an ASP page? *


I'm still struggling with this.

I've tried combinations of XMLDocument.load/XMLDocument.loadXML (Request/Request.InputStream). No luck.

In order to test this, if I set Receiver.aspx to

<%@Page AspCompat=true Language=VB ValidateRequest=false%>
<%
    Dim reqLen As Integer = Request.TotalBytes

'Create a piece of XML to send back

    Dim strResponse As String = "<?xml version=""1.0""?><equis><comment> " & reqLen & " bytes</comment><footer>End of document</footer></equis>"

'Send the response back
response.write(strResponse)
%>

The result is always:

XML DOC posted off:
 Jenny  
Target URL: http://localhost:81/Receiver.aspx
XML DOC Received back: 
  0 bytesEnd of document

So, no input stream at all? Why?


Solution

  • Finally I succeeded in this. Googled and duckduckgoed a lot, slept less. Installing Fiddle and playing with it made me to see that SimplePoster2 was sending nothing at all, and noticed that Receiver2 with StreamReader was really receiving and responding to XML composed and sent directly from Fiddler.

    Sooooo many hours spent and lost like tears in the rain... <= ;-) geek blink!

    I share with you my lessons adquired.

    Final SimplePoster2.aspx:

    <%@Page AspCompat=true Language = VB%>
    
    <HTML>
    <HEAD>
    </HEAD>
    <%
    
        'Put together some XML to post off
        Dim xmlString As String = "<?xml version=""1.0""?>" & vbCrLf
        xmlString = xmlString & "<Req1>" & vbCrLf
        xmlString = xmlString & " <Name>Jenny</Name>" & vbCrLf
        xmlString = xmlString & "</Req1>"    
    
        'Load the XML into an XMLDOM object
        Dim msXMLDocu As Object = Server.CreateObject("Msxml2.DOMDocument.6.0")
        'msXMLDocu.ValidateOnParse = True
        msXMLDocu.async = False
        msXMLDocu.LoadXML(xmlString)
    
        'Set the URL of the receiver
        Dim sURL As String = "http://localhost:81/Receiver2.aspx"
    
        'Call the XML Send function (defined below)
        Dim xmlPoster As Object = Server.CreateObject("MSXML2.ServerXMLHTTP")
        xmlPoster.open("POST", sURL, False)
        xmlPoster.setRequestHeader("Content-Type", "text/xml")
        xmlPoster.send(msXMLDocu.xml)
        Dim NewXmlDoc = Server.CreateObject("Msxml2.DOMDocument.6.0")
        NewXmlDoc.async = False
        'NewXmlDoc.ValidateOnParse = True
        NewXmlDoc.LoadXML(xmlPoster.responseText)
    
        'We receive back another XML DOM object!
    
        'Tell the user what happened
        Response.Write("<b>XML DOC posted off:</b><br>")
        Response.Write(msXMLDocu.XML & "<br>")
        Response.Write("<b>Target URL:</b> " & sURL & "<br>")
        Response.Write("<b>XML DOC Received back: </b><br>")
        Response.Write(NewXmlDoc.Xml)
    
    %>
    </HTML>
    

    Do NOT: [MSXML2.ServerXMLHTTP].send([Msxml2.DOMDocument.6.0]).

    Don't try to send XML Doc object, send its content as string.

    DO: [MSXML2.ServerXMLHTTP].send([Msxml2.DOMDocument.6.0].xml).

    Simple Receiver2.aspx:

    <%@Page AspCompat=true Language=VB ValidateRequest=false%>
    <%
        Dim strResponse As String
        Dim reqLen As Integer = Request.TotalBytes
    
        If (reqLen > 0) Then
            Request.InputStream.Position = 0
            Dim sReader As System.IO.StreamReader = New System.IO.StreamReader(Request.InputStream)
            Dim inputStr As String = sReader.ReadToEnd()
    
            Dim msXmlDocu As Object = CreateObject("Msxml2.DOMDocument.6.0")
            msXmlDocu.async = False
            Dim xmlLoaded As Boolean = msXmlDocu.loadXML(inputStr)
            If (xmlLoaded) Then
                Dim listItem As Object = msXmlDocu.selectnodes("Req1")
    
                strResponse = "<?xml version=""1.0""?>" & vbCrLf & "<doc><status>OK</status><length>" & reqLen & " bytes</length>"
                strResponse = strResponse & "<Person>" & vbCrLf
    
                'For the purposes of this example we modify
                'the response based on the request
                Dim node
                Dim name
                For Each node In listItem
                    name = node.selectsinglenode("Name").firstchild.nodevalue
                    strResponse = strResponse & " <Name>Thanks " & name & "</Name>" & vbCrLf
                Next
    
                strResponse = strResponse & "</Person></doc>"
    
                'strResponse = "<?xml version=""1.0""?><doc><status>OK</status><length>" & reqLen & " bytes</length><content>" & stri & " </content></doc>"
            Else
                'Create a piece of XML to send back
                strResponse = "<?xml version=""1.0""?><doc><status>Error</status><reason>Data posted, but could not load XML Document</reason></doc>"
            End If
        Else
            'Create a piece of XML to send back
            strResponse = "<?xml version=""1.0""?><doc><status>Error</status><reason>No data posted available</reason></doc>"
        End If
    
    
            'Send the response back
            Response.Write(strResponse)
    %>
    

    Do NOT: [Msxml2.DOMDocument.6.0].load(Request) or [Msxml2.DOMDocument.6.0].load(Request.InputStream)

    Do:

    Request.InputStream.Position = 0
    Dim sReader As System.IO.StreamReader = New System.IO.StreamReader(Request.InputStream)
    Dim inputStr As String = sReader.ReadToEnd()
    [Msxml2.DOMDocument.6.0].loadXML(inputStr)
    

    [Msxml2.DOMDocument.6.0] only has 2 methods: Load reads a file with XML text in, LoadXML inputs a XML string.

    Don't try to input Request in MSXML directly. Read the input with a StreamReader, convert it to string, and then enter it into MSXML. Now you can work with received XML as desired.