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






2.63/5 (5 votes)
Sep 29, 2004
4 min read

50685

372
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.