Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

When XML is Too Much, Lite-ly Post Data to Your Server

0.00/5 (No votes)
29 Sep 2004 1  
Posting data to another server in ASP.NET can be a problem.

Introduction

XML is great but sometimes it is simply an overkill. Once upon a time it was possible to post to the server and get a response without all the fuss. Let�s compare for just a second why we might want to do a lite weight post of data. For one, when it�s your server you are posting to and the application is �well known� XML can get in the way. In many cases, you just want to dump a block of data that has only transient value, process it and get a quick response.

Background

What I wanted to do is use the ASP.NET Frameworks for our application and just hit an outside server with a �data packet� and get back a value. I could have developed all this in an XML application or even a web service, but that seemed like a lot of code to just post. What I found is that what we used to do in old ASP was a lot harder in ASP.NET and that there was little information on HTTP-POST it seemed because of everyone�s preoccupation with XML.

Well here is an ASP.NET post/response local server for remote server application. There is plenty of room for expansion on this one (you could even inject XML.) However I must acknowledge a source for a part of the client side code, Gopalan Suresh Raj for his very clear article, Making GET and POST requests on web pages.

The project

You need a couple of web sites to test the code. One is your �client local website� and the other is your �remote server website� with the object that the page you browse on the client local website, will post (a data packet) to the remote server website. The remote server website will �process� the post, respond to your client local server, which in turn displays the page you requested in your browser. I developed both the projects using VS 2005 Beta 1, so if you are using VS 2003 you should create your two projects and cut and paste in the code.

Code behind for the local web server.

This is the website that will post to a remote server website. This page should include a frame to display the results or you will get an error. How it works? When you call this page in your local server with the browser, it generates a post to the remote server. In turn the remote server reads the incoming stream and decodes the stream. The remote server then does any necessary processing to the data and generates the response back to the local server. At this point, the local server can finish its Page_Load and respond back to the browser request, now with data from the local server and from the remote server.

public partial class Default_aspx
{
    //declare some useful variables

    //will hold the content to be posted to remote server

    private string sPostDataBlock = ""; 
    //your remote server that has your post receiving/processing page            

    private string sBDsite = "http://t2.cyant.com"; 
    //will hold the content of a returned response to your post

    private string rtnPost = "";                    


    private void Page_Load(object sender, System.EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            // build the post data block in a string

            MakeHTMLStringPost();
            // Posts and receives a response string 

            // from the remote server                

            rtnPost = postToURL(sBDsite);        

            // process the returned response

            // call your response process to do whatever 

            // you want with the return

            ParseHTMLresponse(rtnPost);            

            //other code here

        }
    }

    private string ParseHTMLresponse(string sHTMLmsg)
    {
        //Any response processing of the returned data

        //just show it on the screen for now 

        //(**See function def for important usage)

        htmlDisplayResponse(sHTMLmsg);        
        return "";
    }

    private void buildDataBlock(string field, string value)
    {
        //creates a Key/value pair with a pair seperator 

        //character (|) appended

        //string field name (equiv to a dict key)

        sPostDataBlock += field;  
        //seperator character      

        sPostDataBlock += "=";  
        //string representation of the value to be posted        

        sPostDataBlock += value; 
        //remote server expects that each data item

        //be seperated with the pipe character       

        sPostDataBlock += "|";           
                                        
    }

    private void MakeHTMLStringPost()
    {
        sPostDataBlock = "";        //clear datablock


        //call any code here that would get the 

        //data that you want to post to a server

        string fieldKeyName = "f0";
        string fieldValue = "test 1";
        buildDataBlock(fieldKeyName, fieldValue);
        //...

        //...

        buildDataBlock("f1", "1");
        //repeat process until all of your 

        //post is in sPostDataBlock

    }

    #region WebRequest POST and Response methods

    /// <SUMMARY>

    /// postToURL is a method that forces a 

    /// POST of data to a specified URL

    /// A HTTP POST is a combination of a write to the Web Server

    /// and an immediate read from the Web server

    /// </SUMMARY>

    /// <PARAM name="sURL"></PARAM>

    private string postToURL(string sURL)
    {
        //results of send request

        bool results = false; 
        //return response content       

        string htmlContent = ""; 
           
        // Create the Web Request Object

        WebRequest request = WebRequest.Create(sURL);
        // Specify that you want to POST data 

        request.Method = "POST";                      
        request.ContentType = "application/x-www-form-urlencoded";
        if (sURL != null)
            // write out the data to the web server

            results = writeToURL(request);            
        else
            request.ContentLength = 0;

        if (results)
            // read the response from the Web Server

            htmlContent = retrieveFromURL(request);   
        return htmlContent;
    }

    /// <SUMMARY>

    /// writeToURL is a method that writes the contents of

    /// a specified URL to the web

    /// </SUMMARY>

    /// <PARAM name="request"></PARAM>

    /// <PARAM name="data"></PARAM>

    private bool writeToURL(WebRequest request)
    {
        //sPostDataBlock is a page variable

        //that has been loaded prior to call

        if (sPostDataBlock != "")     
                                     
        {
            byte[] bytes = null;
            // Get the data that is being posted 

            // (or sent) to the server

            bytes = 
               System.Text.Encoding.ASCII.GetBytes(sPostDataBlock);
            request.ContentLength = bytes.Length;
            // 1. Get an output stream from the request object

            Stream outputStream = request.GetRequestStream(); 
            // 2. Post the data out to the stream   

            outputStream.Write(bytes, 0, bytes.Length);
            // 3. Close the output stream and send the data 

            // out to the web server        

            outputStream.Close();                    
            return true;    //send data

        }
        else
            return false;
    }

    /// <SUMMARY>

    /// retrieveFromURL is a method that retrieves the contents of

    /// a specified URL in response to a request

    /// </SUMMARY>

    /// <PARAM name="request"></PARAM>

    /// <RETURNS></RETURNS>

    private string retrieveFromURL(WebRequest request)
    {
        // 1. Get the Web Response Object from the request

        WebResponse response = request.GetResponse();        
        // 2. Get the Stream Object from the response

        Stream responseStream = response.GetResponseStream();    
        // 3. Create a stream reader and associate it with 

        // the stream object

        StreamReader reader = new StreamReader(responseStream);    
        // 4. read the entire stream

        return reader.ReadToEnd();                
    }

    /// <SUMMARY>

    /// htmlDisplayResponse Display the content 

    /// on the web page. 

    /// Primary purpose is for troubleshooting 

    /// the response message.

    /// </SUMMARY>

    /// <PARAM name="sResponse"></PARAM>

    private void htmlDisplayResponse(string htmlContent)
    {
        /*
            Place this code inside the form tags to 
            create a test display frame.
            <frame id=htmlDisplayArea Wrap="True" 
            MaintainState="false" 
            runat="server"></frame>
        */
        htmlDisplayArea.InnerHtml = "";
        if (htmlContent != null)
            // Display the content on the web page

            htmlDisplayArea.InnerHtml += htmlContent;    
    }

    #endregion

}

Code behind for the remote server that receives the datapost from the "local" and returns a response back to the local server.

Note: Delete all HTML from the source of the target page except for the page directives at the top. How it works? When you make a page request to your local server with your browser the server executes the local ASPX page which includes the post to the remote server. Here in the remote server the local server is the client and the page it called will accept the request. That is fine except it hasn't a clue about what to do with a stream of ASCII encoded data. This is the fun part, we simply open a stream object to read the incoming data, count the bytes, convert the ASCII encoded data to a local string. Now the client (local server) is still waiting for a response so that it can move on. We can process the data and make a response based on the data or we could simply respond with some value that the client expects so that we release it to finish delivering the page to the browser.

public partial class Default_aspx
{

    private void Page_Load(object sender, System.EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            Stream str = null;
            string strmContent = "";
            string sOut = "";
            int cntr = 0;
            int strLen = 0;
            int strRead = 0;

            //request the input to the page

            str = Request.InputStream;            
            //get the length of the incoming stream

            strLen = (int)(str.Length);            
            //make a Byte array the size of the stream

            Byte[] strArr = new Byte[strLen];        
            //read the stream into the array

            strRead = str.Read(strArr, 0, strLen);        

            //it was ASCII encoded before it was sent to us

            ASCIIEncoding ascii = new ASCIIEncoding();    
            //get the ASCII array into a regular "string" here

            strmContent = ascii.GetString(strArr);        
            //save it so we can echo it back if we want to

            sOut = strmContent;                

            //split the content string on the pipe character.

            string[] aStrContent = 
                        strmContent.Split(new Char[] { '|' });    
            //get the number of elements in array dimension 0

            cntr = aStrContent.GetUpperBound(0);                
            //do something with the data...

            //...

            //...


            //...return something to the requesting page

            //echo the response and the count of items.

            Response.Write(sOut + " " + cntr.ToString());            
        }
    }
}

For the purpose of testing you need to insert a frame code section (see the default.aspx in the project) in your local web page, so that the code behind can display the response from the remote server.

A word about the System references: In addition to the normally included System.xxxx statements, you must include the following two references in the code behind.

using System.IO;
using System.Text;

If you simply need to write a block of data to a remote server and have that server respond back to your server so that you can do further processing, then this a simple solution and best of all it is all .NET.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here