QueryString, Params, and Forms - Oh My!
Data can be passed between Web pages in a variety of ways. Know the differences and where each might be most useful.
By Josef Finsel
I've encountered many different examples on the Web that read data from a Web form. Sometimes they use QueryString, sometimes they use Params, and sometimes they use Forms. Which is correct?
- BR from Dayton, Ohio
To understand the differences between these, you first need to understand the two main methods used for transporting Web form data across the Web: POST and GET. To demonstrate this, I'll use three Web forms: Get.aspx, Post.aspx, and Receiver.aspx. GET and POST will both contain Web forms that post to Receiver but will use the two different methods of transporting data.
To being with, create the three forms and then open Get.aspx. Change the Document PageLayout property to FlowLayout and add these three HTML controls (not Web Forms controls): A textbox for storing the user's name, a submit button, and a hidden field with the value of HiddenText. Because we're not going to manipulate these objects programmatically, they simply need to have names so the data will be passed along. Now there's one last thing you need to do before you're ready to use this form - modify the form's properties.
Every Web form includes a <FORM> tag that defaults to posting the form back to itself. When you're finished, the HTML code should look like this:
<form id="Form1" method="get" action="Receiver.aspx">
Please enter your name:
<INPUT name="txtName" type="text">
<INPUT type="submit" value="Submit">
The first thing to note is that you have modified the default method of POST to be GET, which makes this a good time to talk about the differences between the two. Whenever you use a form on a Web page, it needs to pass the named values (txtName and txtHiddenData being the two you are passing in this form) to whatever page is going to process the data. The GET method passes the named values as part of the URL. When I run this from my machine, enter data in the textbox, and submit, I get this URL:
The question mark (?) indicates the URL contains data. Each named value has the name to the left of the equals (=) sign and the value to the right, and multiple values are separated with an ampersand (&). A quick look at the previous URL shows one of the drawbacks to using the GET method: The URL includes all the data and the hidden field isn't very hidden. For this reason, it's good not to use GET when using passwords and such. The other limitation of this way of passing data is that the amount of data you can send needs to fit in the Web browser's address window, and the server must be able to process long URLs. Getting beyond 1,024 characters makes it more difficult to use the GET method of passing data.
But it the GET method does have advantages. For instance, the following link generates a random quote as a graphic image using the QueryString format to determine the font, size, etc., that goes into the quote. This makes the image much more flexible than it would be if you had to create separate .aspx files for each type of quote and have people link to them. The following link creates the image underneath it, and every time you refresh this page a new quote comes up. Give it a try:
Now that we've looked at GET and its usefulness and limitations, it's time to take a quick look at the POST form. The only difference between Post.aspx and Get.aspx is the form's method changes from GET to POST. Everything else stays the same, but this changes way the data is passed to the server. Instead of appending the named values to the URL, they are put into the headers sent to the server. This not only makes the values more secure by keeping them out of the URL, you can post more data to the server this way. It's also possible to pass Unicode data because the headers allow it; the URL, however, doesn't.
Now that we've got the pages to POST and GET, let's work on the one to demonstrate how to access the data we're sending. As I mentioned earlier, the data being passed between the forms is in the form of named value pairs, much like the old dictionary object. The easiest way to access the data is through the NameValueCollection class. Here is the code for the QueryString collection, which is duplicated for the Forms and Params collections:
// If here's at least one named value
if (colQS.AllKeys.Length != 0)
//Loop through named values, print name and value
strOutput.Append("<B>" + colQS.AllKeys[iLoop] +
"</B> = " + colQS.GetValues(iLoop).GetValue(0)
else // No data available
strOutput.Append("No QueryString Data Available");
The first step is to create a NameValueCollection and set it equal to the Request.QueryString object. The two main parts of the NameValueCollection you need are AllKeys (the names) and GetValues (the values associated with those names). Using AllKeys.Length allows you to determine whether there are any name-value pairs. If so, you can loop through the pairs and print the name of the value from AllKeys and the value from GetValue(0). Now you're only passing in single values, so you can use GetValue(0), but it is possible to have variables with the same name. This creates an array of values you'd need to loop through using a second counter. Finally, you append this data to a StringBuilder object so you can post it through a literal object on the Web form.
Although this code handles QueryString, Form, and Params the same way, this is a good time to talk about the difference between Params and the other two. The Params object grants you access to the named value without knowing where it is. In classic ASP, it was common to write a function stored in an include file for accessing form data. This function looked something like this:
'Purpose : Retrieve values from the POST or
'GET Method (GET HAS PRIORITY)
IF(not ISEmpty(Request.QueryString(sRequestName))) THEN
RequestForm = Request.QueryString(sRequestName)
RequestForm = Request.Form(sRequestName)
The Params object works the same way, except it also includes the Cookie and Header objects as well, which leads to an important question based on the comment in the previous code snippet: If you somehow have a same-named variable in both QueryString and the form, which one shows up in the Params object? To find out, let's make a modification to the FORM tag in Post.aspx and add to it a QueryString variable called txtHiddenText with a value different from the one in the form:
<form id="Form1" method="post" action="Receiver.aspx?txtHiddenData=QSHiddenData">
Save the page, bring it up in the browser, submit it, and what do you get? Surprisingly enough, you get QSHiddenData, but not HiddenData. Does this mean the named variable from the POST form is gone? Nope. Remember when I said we were looking only at GetValue(0)? That code won't work here. Because the variables have the same name, they stored under one key in a string array. Unfortunately, there is no way to tell which member of the array came from POST and which came from GET.
So, as with many things in ASP.NET, there is no right or wrong way to access the data from a form. If you are sending the data through POST, you either can use the Form or Params object. If you are using GET, you can use either QueryString or Params. If you have a busy Web site, you're probably better off not using Params to cut down on the overhead.
As for whether you use POST or GET depends on whether the data should appear in the URL. Passwords in the URL are generally a bad idea, but if you are going to provide a dynamic Web page other people can link to, GET is the way to go. POST is necessary if you want to hide the data in the headers, have a lot of data, or want to use Unicode.
Have a question? Send it to [email protected].
Josef Finsel is a software consultant with G.A. Sullivan, a global software development company. He has published a number of VB and SQL Server-related articles, and he is working on the syntax for FizzBin.NET, a programming language that works the way programmers have always suspected. He also wrote The Handbook for Reluctant Database Administrators (Apress).