ASP.NET Basics (part 7): Command And Control

Dynamically generate forms using ASP.NET's server controls and Request object.

Applying The Theory

Last time out, I gave you a crash course in better software design, by showing you how to abstract parts of your C# code into reusable functions. You've already learned how to add flexibility to your functions by allowing them to accept different arguments, and how to obtain one (or more) return values from them. You also know a little bit more about variable scope, and have a better understanding of how C# treats variables inside and outside functions.

Enough theory then - let's get into something practical. Over the course of this article, I'm going to initiate you into using ASP.NET in your Web development, by showing you how the technology can be used in one of the most common applications of a Web development language - form input. Throughout the following pages, I'm going to devote lots of space to a discussion of how ASP.NET can be used to extract and use data from HTML forms, and how it can be used to programmatically generate forms using so-called "server controls", which let you build everything from simple text fields to drop-downs and check boxes.

The Last Action Hero

HTML forms are typically used to obtain information from visitors to a Web site - things like their name, mailing address, phone number, and the like - and this information is then processed in a variety of different ways. Some sites store it in a database; others email it to the webmaster; and still other simply redirect it to the trash basket. By using ASP.NET and C# to process a form, you can write simple code snippets that accomplish all of these actions.

Let's begin with a simple example.

<html>

<head>
<basefont face="Arial">
</head>

<body>

<center>
<form method="GET" action="sanctum.aspx">
<table cellspacing="5" cellpadding="5" border="0">

<tr>
<td>
<font size="1">Who dares to disturb the Council?</font>
</td>
<td align="left">
<input type="text" name="name" size="10">
</td>
</tr>

<tr>
<td colspan="2" align="center">
<input type="submit">
</td>
</tr>

</table>
</form>

</center>
</body>

</html>

The most critical line in this entire page is the <form> tag.

<form method="GET" action="sanctum.aspx">
...
</form>

As you probably already know, the ACTION attribute of the <FORM> tag specifies the name of the server-side script - "sanctum.aspx" in this case - that will process the information entered into the form, while the METHOD attribute specifies the manner in which the information will be passed.

Once the form has been submitted, the script "sanctum.aspx" is called upon to parse the data entered into the form. At this point, the script simply reads the name entered into the form, and displays a message containing that name; however, at a later point, it will be modified to grant or deny access based on the name entered.

<html>
<head>
<basefont face="Arial">
</head>

<body>
<center>
<script language="c#" runat="server">
void Page_Load()
{

    // sanctum.aspx

    // define the variables
    string fname;

    // assign values
    fname = Request.QueryString["name"];

    // print the details
    Response.Write("Welcome to the Inner Sanctum, " + fname + "!");

}
</script>
</center>
</body>
</html>

And now, if you enter some data into the form (say, "joe"), this is what you should see:

Welcome to the Inner Sanctum, joe!

An explanation is in order here. As always, the first step is to define the variables that will be used throughout the script - in this case, the variable "fname".

<%
    // define the variables
    string fname;
%>

Next, the value of the form variable "name" has to be assigned to the C# variable "fname" - this is accomplished with the use of the "QueryString" property of the Request object, which accepts the name of a form control (in this case, the solitary text field in the form) as a parameter and returns the value entered into that control.

<%
    // assign values
    fname = Request.QueryString["name"];
%>

Unlike many other objects in C#, the Request object is an "implicit" object, so called because you do not need to explicitly create an instance of the object when you want to use it. The "QueryString" property is just one of the many properties available in this object - I'll be exploring some of the others as well in this tutorial.

Once the value of a form variable has been assigned to a C# variable, it can be treated in exactly the same manner as other C# variables. In the example above, the Write() method of the Response object handles the task of printing the welcome message, with the name incorporated into it.

<%
    // print the details
    Response.Write("Welcome to the Inner Sanctum, " + fname + "!");
%>

You can also use the POST method (which offers greater security and reliability) to process form data - simply alter the HTML form so that the METHOD used is POST.

<form method="POST" action="sanctum.aspx">
...
</form>

You'll also need to update the ASP.NET script "sanctum.aspx" to use POST data instead of the URL GET method. This update consists of using the Request object's "Form" property instead of the "QueryString" property, as illustrated below:

<html>
<head>
<basefont face="Arial">
</head>

<body>
<center>
<script language="c#" runat="server">
void Page_Load()
{
    // sanctum.aspx

    // define the variables
    string fname;

    // assign values
    fname = Request.Form["name"];

    // print the details
    Response.Write("Welcome to the Inner Sanctum, " + fname + "!");

}
</script>
</center>
</body>
</html>

You can add a conditional test to deny access to all but the most favoured:

<html>
<head>
<basefont face="Arial">
</head>
<body>
<center>
<script language="c#" runat="server">
void Page_Load()
{

    // sanctum.aspx

    // define the variables used
    string fname;

    // assign values
    fname = Request.Form["name"];

    // print the details
    if (fname == "thomson")
    {
        Response.Write("Welcome to the Inner Sanctum, Commander Thomson!");
    }
    else
    {
        Response.Write("Get lost, loser, before we beat you to a pulp!");
    }

}
</script>
</center>
</body>
</html>

Requesting More

Before moving on to more complex form processing, let's dawdle a little bit with our new acquaintance, the Request object, and find out a little more about it. The Request object is one of the more useful objects you'll encounter in your ASP.NET development, since the concept of a request and a response is the backbone of the client-server architecture. The Internet is, after all, a vast network of servers, with each of us accessing it through clients. For each bit of information that we wish to access, there is a "request" sent to some server that in turn sends the appropriate "response" back to the browser (client).

In addition to the "QueryString" and "Form" properties you just saw, the Request object also comes with a bunch of other useful properties - the following example demonstrates some of them:

<html>
<head>
<basefont face="Arial">
</head>
<body>

<table border="1" cellspacing="5" cellpadding="5">
<tr>
<td><b>Variable</b></td>
<td><b>Value</b></td>
</tr>

<tr>
<td>Hostname</td>
<td>
<% Response.Write (Request.UserHostName) %>
</td>
</tr>

<tr>
<td>Host address</td>
<td>
<% Response.Write (Request.UserHostAddress) %>
</td>
</tr>

<tr>
<td>URL</td>
<td>
<% Response.Write (Request.Url) %>
</td>
</tr>

<tr>
<td>Path to script</td>
<td>
<% Response.Write (Request.PhysicalPath) %>
</td>
</tr>

<tr>
<td>Browser</td>
<td>
<% Response.Write (Request.UserAgent) %>
</td>
</tr>

</table>
</body>
</html>

And when you view the file in your browser, you'll probably see something like this:

Why stop there? ASP.NET also provides a Browser object (a property of the Request object that, coincidentally, is itself an object) that provides information about the HTTP client you're using. Here is an example of how it can be used:

<html>
<head>
<basefont face="Arial">
</head>
<body>

<table border="1" cellspacing="5" cellpadding="5">
<tr>
<td><b>Variable</b></td>
<td><b>Value</b></td>
</tr>

<tr>
<td>Client version</td>
<td>
<% Response.Write (Request.Browser.Version) %>
</td>
</tr>

<tr>
<td>Supports tables?</td>
<td>
<% Response.Write (Request.Browser.Tables) %>
</td>
</tr>

<tr>
<td>Supports frames?</td>
<td>
<% Response.Write (Request.Browser.Frames) %>
</td>
</tr>

<tr>
<td>Supports Java applets?</td>
<td>
<% Response.Write (Request.Browser.JavaApplets) %>
</td>
</tr>

<tr>
<td> Supports JavaScript?</td>
<td>
<% Response.Write (Request.Browser.JavaScript) %>
</td>
</tr>

<tr>
<td>JavaScript version supported</td>
<td>
<% Response.Write (Request.Browser.EcmaScriptVersion) %>
</td>
</tr>

</table>
</body>
</html>

Here's the output:

All these variables come in handy if you need to make decisions on the basis of remote variables - as the following example demonstrates:

<script language="c#" runat="server">
void Page_Load()
{
    string browser = Request.UserAgent;

    if(browser.IndexOf("MSIE") >= 0)
    {
        // IE-specific code
        output.Text = "You're using Internet Explorer, aren't you?";
    }
    else if(browser.IndexOf("Mozilla") >= 0)
    {
        // Mozilla-specific code
        output.Text = "Mozilla rocks, dood! Gimme five!";
    }
    else
    {
        // any other browser
        output.Text = "Hmmm, you're using a browser I don't know about. Never mind, you're welcome too!";
    }
}
</script>
<html>
<head></head>
<body>
<asp:label id="output" runat="server" />
</body>
</html>

Note my usage of the IndexOf() method of the "string" object (the "string" datatype, like just about everything else in the .NET environment, is an object, with its own set of properties and methods) - this method is used to scan a string for a specific character sequence. It returns 0 if the sequence cannot be matched, and is thus very useful to run browser detection routines, as in the sample above.

Test Drive

Just as you can access data from text fields in an ASP.NET script, you can also evaluate the state of radio buttons and list boxes. To demonstrate, let's create a more complex form.

<html>
<head>
<basefont face=arial>
</head>

<body>
<h2> Survey</h2>

<form action="result.aspx" method="POST">

<p>

Do you plan to buy a car?
<input type="radio" value="Y" name="buycar">Yes
<input type="radio" value="N" name="buycar">No

<p>

What is your budget for the car, if you were to buy one?
<select name="budget">
    <option value="5" selected>&gt; $1,000,000</option>
    <option value="4">&gt; $500,000 and &lt; $1,000,000 </option>
    <option value="3">&gt; $250,000 and &lt; $500,000</option>
    <option value="2">&gt; $100,000 and &lt; $250,000</option>
    <option value="1"> &lt; $100,000</option>
</select>

<p>
<input type="submit" value="Submit Feedback">

</form>

</body>
</html>

And here's "result.aspx".

<script language="c#" runat="server">
void Page_Load()
{
    // result.aspx

    // define the variables and assign values
    string budget_string = Request.Form["budget"];
    string buycar = Request.Form["buycar"];

    // convert string to number
    int budget = Convert.ToInt32(budget_string);

    // process and display

    // "Y" to buying a car
    if (buycar == "Y")
    {
        if(budget > 3)
        {
            output.Text = "So you're looking for a Ferrari or a Porsche, hmmm?";

        }
        else
        {
            output.Text = "We have the latest models from Ford and GM available for a test drive";
        }

    }
    else
    {
        output.Text = "Hey, why not? Everybody has one these days...";
    }

}
</script>
<html>
<head>
<basefont face="Arial">
</head>
<body>
<center><asp:label id="output" runat="server" /></center>
</body>
</html>

As you can see, evaluating radio buttons and list boxes is almost exactly the same as evaluating regular text fields.

The Taste Test

Arrays come in particularly handy when dealing with form elements like checkboxes and multiple select list boxes. Take a look at the following form, which includes a bunch of checkboxes:

<html>
<head>
<basefont face="Arial">
</head>
<body>

Pick your favourite pizza toppings, and we'll match them to television shows:
<br>
<form action="pizza.aspx" method="POST">
<input type="checkbox" name="shows" value="Ally McBeal">nuts
<input type="checkbox" name="shows" value="Buffy The Vampire Slayer">garlic
<input type="checkbox" name="shows" value="Sex And The City">oysters
<input type="checkbox" name="shows" value="Joe Millionaire">caviar
<input type="checkbox" name="shows" value="Friends">cheese
<input type="checkbox" name="shows" value="The West Wing">pepperoni
<br>
<input type="submit" name="submit" value="Select">
</form>

</body>
</html>

Now, once the form is submitted, the ASP.NET script "pizza.aspx" is responsible for processing the states of the various checkboxes. Data from the checkboxes is assigned to an array, and then this array is used to recreate a list of the selected items. Take a look.

<script language="c#" runat="server">
void Page_Load()
{

    // pizza.aspx - process list of selected toppings

    // split the comma-separated value into an Array
    string[] Shows = Request.Form["shows"].Split(',');

    output.Text = "<ul>";

    // print by iterating through array
    for(int counter = 0; counter < Shows.Length; counter++)
    {
        output.Text = output.Text + "<li>" + Shows[counter];
    }

    output.Text = output.Text + "</ul>";

}
</script>
<html>
<head>
<basefont face="Arial">
</head>
<body>
<center><asp:label id="output" runat="server" /></center>
</body>
</html>

As you can see, the first order of business is to create an array to hold the checkbox data - in this case, the array "Shows". Then, the Request object is used to obtain the values of the selected items (in the form of a comma-separated list of values) and these values are then assigned to the "Shows" array using the "Split" method of the string object. A "for" loop is then used to create a list of the selected items.

This technique can also be used with multiple-select list boxes - here's the same example, rewritten to use a list box instead of a series of checkboxes.

<html>
<head>
<basefont face="Arial">
</head>
<body>

Pick your favourite shows:
<br>
<form action="pizza.aspx" method="POST">
<select name="shows" multiple>
    <option value="Ally McBeal">nuts</option>
    <option value="Buffy The Vampire Slayer">garlic</option>
    <option value="Sex And The City">oysters</option>
    <option value="Joe Millionaire">caviar</option>
    <option value="Friends">cheese</option>
    <option value="The West Wing">pepperoni</option>
</select>
<input type="submit" name="submit" value="Select">
</form>

</body>
</html>

Obviously, the server-side script "pizza.aspx" requires no changes at all.

A Matter Of Control

I have repeatedly used the ASP.NET "label" control to display the output of my scripts in previous examples. However, this is not the only control available in ASP.NET. In fact, each form construct demonstrated in previous examples has a corresponding server control.

Take for example, the "textbox" control, which is similar to the "text" form control. It's pretty easy to use this in a script - as the following example demonstrates, by rewriting the very first example in this article:

<script language="c#" runat="server">
void Page_Load()
{
    if(name.Text != "")
    {
        // print the details
        Response.Write("Welcome to the Inner Sanctum, " + name.Text + "!");

    }
}
</script>
<html>
<head>
<basefont face="Arial">
</head>
<body>
<center>
<form runat="server">

<table cellspacing="5" cellpadding="5" border="0">

<tr>
<td>
<font size="1">Who dares to disturb the Council?</font>
</td>
<td align="left">
<asp:textbox id="name" runat="server" />
</td>
</tr>

<tr>
<td colspan="2" align="center">
<input type="submit" name="submit" value="Enter">
</td>
</tr>

</table>

</form>
</center>
</body>
</html>

So, what's new here? First up, the "form" element:

<form runat="server">
...
</form>

The "runat" attribute, when set to a value of "server" instructs ASP.NET to process the form on the server, and makes the server responsible for maintaining the state of the page. Why is this useful? You'll see shortly.

Next, the "textbox" control. Nothing too complicated here, but note that the control is assigned a name - funnily enough, called "name" in this example - via the "id" attribute:

<asp:textbox id="name" runat="server" />

The final piece of the puzzle is the code that takes care of displaying the welcome message once the form is submitted:

void Page_Load()
{
    if(name.Text != "")
    {
        // print the details
        Response.Write("Welcome to the Inner Sanctum, " + name.Text + "!");

    }
}

Take a closer look at the "if" condition - it looks for a text value in the "textbox" server control called "name", and then displays a message incorporating that value. The data entered by the user is accessed via the "Text" property of the server control.

So what was so different about this example, as compared to the earlier ones? For one, I didn't specify an ACTION for the form. I didn't need to - instead, the moment I set the "runat" attribute to "server", the server took over and automatically submitted the form back to the same script for processing.

One final note: once the form is submitted, you will notice that the URL contains a new variable, "__VIEWSTATE", which is passed along. This is a built-in variable introduced by ASP.NET to maintain the state of the page.

You'll have noticed that in all the earlier examples, I have used two pages - a single HTML page containing the form, and a separate C# script which processes the form input and generates appropriate output. However, the method above provides an elegant method to combine those two pages into one using the "runat=server" feature of ASP.NET.

Alien Invasion

Of course, there is a lot more to these ASP.NET controls than just labels and text boxes. Take a look at the next example that demonstrates other form controls such as checkboxes, radio buttons, drop down lists and much more.

<script language="c#" runat="server">
void Page_Load()
{
    // check if the form has been submitted
    if(Request.QueryString["submit"] == "Register")
    {

        output.Text = "You have entered the following:<br>";

        // name field
        output.Text = output.Text + "Name:" + name.Text + "<br>";

        // species field
        output.Text = output.Text + "Species:" + species.Text + "<br>";

        // species type field
        output.Text = output.Text + "Species type: " + speciesType.SelectedValue + "<br>";

        // immunization field
        output.Text = output.Text + "Immunization against: ";
        for(int counter = 0; counter < immunization.Items.Count; counter++)
        {
            if(immunization.Items[counter].Selected)
            {
                output.Text = output.Text + immunization.Items[counter].Text + ",";
            }
        }

        output.Text = output.Text + "<br>";

        // address field
        output.Text = output.Text + "Address:" + address.Text + "<br>";

    }

}

</script>

<html>
<head>
<basefont face="Arial">
</head>
<body>
<center><asp:label id="output" runat="server" /></center>
<center>
<form method="GET" runat="server">
<table cellspacing="5" cellpadding="5" border="0">

<tr>
<td colspan="2" align="center"><font color="red" size="4">Alien Registration Center (ARC)</font></td>
</tr>

<tr>
<td>Name</td>
<td align="left"><asp:textbox id="name" runat="server" /></td>
</tr>

<tr>
<td>Species</td>
<td align="left"><asp:textbox id="species" runat="server" /></td>
</tr>

<tr>
<td>Species type</td>
<td align="left">
    <asp:radiobuttonlist id="speciesType" runat="server">
        <asp:listitem id="carbon" runat="server" value="Carbon-based"/>
        <asp:listitem id="other" runat="server" value="Other"/>
    </asp:radiobuttonlist>
</td>
</tr>

<tr>
<td>Residence</td>
<td align="left">
    <asp:dropdownlist id="residence" runat="server" >
        <asp:listitem value="Temporary Residence"/>
        <asp:listitem value="Permanant Residence"/>
    </asp:dropdownlist>
</td>
</tr>

<tr>
<td>Immunization against</td>
<td align="left">
    <asp:checkboxlist id="immunization" runat="server" >
        <asp:listitem id="spaceworms" runat="server" value="Space Worms" />
        <asp:listitem id="asthma" runat="server" value="Asthma " />
        <asp:listitem id="yellowfever" runat="server" value="Yellow Fever" />
    </asp:checkboxlist>
</td>
</tr>

<tr>
<td>Previous address</td>
<td align="left">
    <asp:textbox  id="address" rows="5" textmode="multiline" runat="server" />
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" name="submit" value="Register"></td>
</tr>

</table>
</form>
</center>

</body>
</html>

This is what the form looks like:

The form is constructed using a variety of different server controls. I start with two text controls:

<tr>
<td>Name</td>
<td align="left"><asp:textbox id="name" runat="server" /></td>
</tr>

<tr>
<td>Species</td>
<td align="left"><asp:textbox id="species" runat="server" /></td>
</tr>

This is followed by a set of radio buttons, created via the "radiobuttonlist" server control. For each radio option, the "listitem" control is used to specify the value:

<tr>
<td>Species type</td>
<td align="left">
    <asp:radiobuttonlist id="speciesType" runat="server" >
        <asp:listitem id="carbon" runat="server" value="Carbon based"/>
        <asp:listitem id="other" runat="server" value="Other"/>
    </asp:radiobuttonlist>
</td>
</tr>

Similarly, I have a "dropdownlist" server control which is used to create a drop-down list box for the type of residence:

<tr>
<td>Residence</td>
<td align="left">
    <asp:dropdownlist id="residence" runat="server" >
        <asp:listitem value="Temporary Residence"/>
        <asp:listitem value="Permanant Residence"/>
    </asp:dropdownlist>
</td>
</tr>

This is followed by a list of checkboxes. Since more than one can be selected, multiple "checkboxlist" server control are used to display the various options:

<tr>
<td>Immunization against</td>
<td align="left">
    <asp:checkboxlist id="immunization" runat="server" >
        <asp:listitem id="spaceworms" runat="server" value="Space Worms" />
        <asp:listitem id="asthma" runat="server" value="Asthma " />
        <asp:listitem id="yellowfever" runat="server" value="Yellow Fever" />
    </asp:checkboxlist>
</td>
</tr>

Finally, a multi-line text box - note the addition of the "textmode" attribute to the "textbox" server control -is used for the address.

<tr>
<td>Previous address</td>
<td align="left">
    <asp:textbox  id="address" rows="5" textmode="multiline" runat="server" />
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" name="submit" value="Register"></td>
</tr>

The form closes with the mandatory "submit" button. Enter some form values, hit the "Register" button, and you should see something like this:

<img src="image4.gif" />

Since the "runat" attribute of the form is set to "server", ASP.NET will submit this form to the same page. As a result, in the Page_Load() function, I have put together some simple C# code to display the data entered by the user. Take a look:

void Page_Load() { // check if the form has been submitted if(Request.QueryString["submit"] == "Register") {

    output.Text = "You have entered the following:`<br>`";

    // name field
    output.Text = output.Text + "Name:" + name.Text + "`<br>`";

    // species field
    output.Text = output.Text + "Species:" + species.Text + "`<br>`";

    // species type field
    output.Text = output.Text + "Species type: " + speciesType.SelectedValue + "`<br>`";

    // immunization field
    output.Text = output.Text + "Immunization against: ";
    for(int counter = 0; counter < immunization.Items.Count; counter++)
    {
        if(immunization.Items[counter].Selected)
        {
            output.Text = output.Text + immunization.Items[counter].Text + ",";
        }
    }

    output.Text = output.Text + "`<br>`";

    // address field
    output.Text = output.Text + "Address:" + address.Text + "`<br>`";

}

}



The code above analyzes each and every server control in the form, and displays the value provided by the user using the ubiquitous "output" label control. Note the manner in which I have used the "SelectedValue" property of the "radiobuttonlist" to get the value of the radio option selected by the user, and my deft handling of the "Selected" property associated with the "checkboxlist" control. Both these properties allow you to test if the particular option has been selected by the user.

And that's about it for today. I started this article with a fast rundown of the various properties of the Request and Browser objects - both help you obtain more information about the users visiting your Web site. This was followed by some examples of processing form input, and a discussion of the various server controls built into ASP.NET that can simplify the task of constructing forms.

In the next segment of this article, I shall dive straight into the world of database interaction with ASP.NET. I'm sure that many of you have been waiting for this. The time is near, so keep watching this space for more.

Note: Examples are illustrative only, and are not meant for a production environment. Melonfire provides no warranties or support for the source code described in this article. YMMV!
This article was first published on 13 Oct 2003.