
Pro CSharp And The .NET 2.0 Platform (2005) [eng]
.pdf
834CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
tag in just a bit. For the time being, let’s look at the sorts of items that can be placed in an HTML form. Visual Studio 2005 provides an HTML tab on the Toolbox that allows you to select each HTML-based UI widget (see Figure 23-4).
Figure 23-4. The HTML controls tab of the Toolbox
Building an HTML-Based User Interface
Before you add the HTML widgets to the HTML <form>, it is worth pointing out that Visual Studio 2005 allows you to edit the overall look and feel of the *.htm file itself using the integrated HTML designer and the Properties window. If you select DOCUMENT from the Properties window (see Figure 23-5), you are able to configure various aspects of the HTML page, such as the background color.
Figure 23-5. Editing an HTML document via VS .NET
Now, update the <body> of the default.htm file to display some literal text that prompts the user to enter a user name and password, and choose a background color of your liking (be aware that you can enter and format textual content by typing directly on the HTML designer):
<html>
<head>
<title>This Is the Cars Website</title>


836 CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
The Role of Client-Side Scripting
A given *.htm file may contain blocks of script code that will be emitted in the response stream and processed by the requesting browser. There are two major reasons why client-side scripting is used:
•To validate user input before posting back to the web server
•To interact with the Document Object Model (DOM) of the target browser
Regarding the first point, understand that the inherent evil of a web application is the need to make frequent round-trips (aka postbacks) to the server machine to update the HTML rendered into the browser. While postbacks are unavoidable, you should always be mindful of ways to minimize travel across the wire. One technique that saves round-trips is to use client-side scripting to validate user input before submitting the form data to the web server. If an error is found (such as not specifying data within a required field), you can prompt the user of the error without incurring the cost of posting back to the web server. (After all, nothing is more annoying to users than posting back on a slow connection, only to receive instructions to address input errors!)
In addition to validating user input, client-side scripts can also be used to interact with the underlying object model (the DOM) of the browser itself. Most commercial browsers expose a set of objects that can be leveraged to control how the browser should behave. One major annoyance is the fact that different browsers tend to expose similar, but not identical, object models. Thus, if you emit a block of client-side script code that interacts with the DOM, it may not work identically on all browsers.
■Note ASP.NET provides the HttpRequest.Browser property, which allows you to determine at runtime the capacities of the browser that sent the current request.
There are many scripting languages that can be used to author client-side script code. Two of the more popular are VBScript and JavaScript. VBScript is a subset of the Visual Basic 6.0 programming language. Be aware that Microsoft Internet Explorer (IE) is the only web browser that has built-in support for client-side VBScript support. Thus, if you wish your HTML pages to work correctly in any commercial web browser, do not use VBScript for your client-side scripting logic.
The other popular scripting language is JavaScript. Be very aware that JavaScript is in no way, shape, or form a subset of the Java language. While JavaScript and Java have a somewhat similar syntax, JavaScript is not a full-fledged OOP language, and thus is far less powerful than Java. The good news is that all modern-day web browsers support JavaScript, which makes it a natural candidate for client-side scripting logic.
■Note To further confuse the issue, recall that JScript .NET is a managed language that can be used to build valid .NET assemblies using a scripting like syntax.
A Client-Side Scripting Example
To illustrate the role of client-side scripting, let’s first examine how to intercept events sent from client-side HTML GUI widgets. Assume you have added an HTML Button (btnHelp) type to your default.htm page that allows the user to view help information. To capture the Click event for this button, activate the HTML view and select your button from the left drop-down list. Using the right drop-down list, select the onclick event. This will add an onclick attribute to the definition of the new Button type:

CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS |
837 |
<input id="btnHelp" type="button" value="Help" language="javascript" onclick="return btnHelp_onclick()" />
Visual Studio 2005 will also create an empty JavaScript function that will be called when the user clicks the button. Within this stub, simply make use of the alert() method to display a clientside message box:
<script language="javascript" type="text/javascript"> <!--
function btnHelp_onclick() {
alert("Dude, it is not that hard. Click the darn Submit button!");
}
// --> </script>
Note that the scripting block has been wrapped within HTML comments (<!-- -->). The reason is simple. If your page ends up on a browser that does not support JavaScript, the code will be treated as a comment block and ignored. Of course, your page may be less functional, but the upside is that your page will not blow up when rendered by the browser.
Validating the default.htm Form Data
Now, let’s update the default.htm page to support some client-side validation logic. The goal is to ensure that when the user clicks the Submit button, you call a JavaScript function that checks each text box for empty values. If this is the case, you pop up an alert that instructs the user to enter the required data. First, handle an onclick event for the Submit button:
<input name="btnSubmit" type="submit" value="Submit" id="btnSubmit" language="javascript" onclick="return btnSubmit_onclick()">
Implement this handler as so:
function btnSubmit_onclick(){
// If they forget either item, pop up a message box. if((defaultPage.txtUserName.value == "") || (defaultPage.txtPassword.value == ""))
{
alert("You must supply a user name and password!"); return false;
}
return true;
}
At this point, you can open your browser of choice and navigate to the default.htm page hosted by your Cars virtual directory and test out your client-side script logic:
http://localhost/Cars/default.htm
Submitting the Form Data (GET and POST)
Now that you have a simple HTML page, you need to examine how to transmit the form data back to the web server for processing. When you build an HTML form, you typically supply an action attribute on the opening <form> tag to specify the recipient of the incoming form data. Possible receivers include mail servers, other HTML files, an Active Server Pages (ASP; classic or .NET) file, and so forth. For this example, you’ll use a classic ASP file named ClassicAspPage.asp. Update your default.htm file by specifying the following attribute in the opening <form> tag:

838 CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
<form name="defaultPage" id="defaultPage" action="http://localhost/Cars/ClassicAspPage.asp" method = "GET">
...
</form>
These extra attributes ensure that when the Submit button for this form is clicked, the form data should be sent to the ClassicAspPage.asp at the specified URL. When you specify method = "GET" as the mode of transmission, the form data is appended to the query string as a set of name/value pairs separated by ampersands:
http://localhost/Cars/ClassicAspPage.asp?txtUserName=
Andrew&txtPassword=abcd123$&btnSubmit=Submit
The other method of transmitting form data to the web server is to specify method = "POST":
< form name="defaultPage" id="defaultPage" action="http://localhost/Cars/ClassicAspPage.asp" method = "POST">
...
</form>
In this case, the form data is not appended to the query string, but instead is written to
a separate line within the HTTP header. Using POST, the form data is not directly visible to the outside world. More important, POST data does not have a character-length limitation (many browsers have a limit for GET queries). For the time being, make use of HTTP GET to send the form data to the receiving *.asp page.
Building a Classic ASP Page
A classic ASP page is a hodgepodge of HTML and server-side script code. If you have never worked with classic ASP, understand that the goal of ASP is to dynamically build HTML on the fly using server-side script and a small set of classic COM objects. For example, you may have a server-side VBScript (or JavaScript) block that reads a table from a data source using classic ADO and returns the rows as a generic HTML table.
For this example, the ASP page uses the intrinsic ASP Request COM object to read the values of the incoming form data (appended to the query string) and echo them back to the caller (not terribly exciting, but it makes the point). The server-side script logic will make use of VBScript (as denoted by the language directive).
To do so, create a new HTML file using Visual Studio .NET and save this file under the name ClassicAspPage.asp into the folder to which your virtual directory has been mapped (e.g., C:\CodeTests\CarsWebSite). Implement this page as so:
<%@ language="VBScript" %>
<html>
<head>
<title>The Cars Page</title> </head>
<body>
<h1 align="center">Here is what you sent me:</h1> <P align="center"> <b>User Name: </b>
<%= Request.QueryString("txtUserName") %> <br> <b>Password: </b>
<%= Request.QueryString("txtPassword") %> <br> </P>
</body>
</html>

CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS |
839 |
Here, you use the classic ASP Request COM object to call the QueryString() method to examine the values contained in each HTML widget submitted via method = "GET". The <%= ...%> notation is a shorthand way of saying, “Insert the following directly into the outbound HTTP response.” To gain a finer level of flexibility, you could interact with the ASP Response COM object within a full script block (denoted by the <%, %> notation). You have no need to do so here; however, the following is a simple example:
<%
Dim pwd
pwd = Request.QueryString("txtPassword")
Response.Write(pwd)
%>
Obviously, the Request and Response objects of classic ASP provide a number of additional members beyond those shown here. Furthermore, classic ASP also defines a small number of additional COM objects (Session, Server, Application, and so on) that you can use while constructing your web application.
■Note Under ASP.NET, these COM objects are officially dead. However, you will see that the System.Web.UI.Page base class defines identically named properties that expose objects with similar functionality.
To test the ASP logic, simply load the default.htm page from a browser and submit the form data. Once the script is processed on the web server, you are returned a brand new (dynamically generated) HTML display (see Figure 23-7).
Figure 23-7. The dynamically generated HTML
Responding to POST Submissions
Currently, your default.htm file specifies HTTP GET as the method of sending the form data to the target *.asp file. Using this approach, the values contained in the various GUI widgets are appended to the end of the query string. It is important to note that the ASP Request.QueryString() method is only able to extract data submitted via the GET method.
If you would rather submit form data to the web resource using HTTP POST, you can use the Request.Form collection to read the values on the server, for example:

840 CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
<body>
<h1 align="center">Here is what you sent me:</h1> <P align="center">
<b>User Name: </b>
<%= Request.Form("txtUserName") %> <br> <b>Password: </b>
<%= Request.Form("txtPassword") %> <br>
</P>
</body>
That wraps up our web development primer. Hopefully, if you’re new to web development you now have a better understanding of the basic building blocks. Before we check out how the .NET platform improves upon the current state of affairs, let’s take a brief moment to bash (which is to say, “critique”) classic ASP.
■Source Code The ClassicAspCars example is included under the Chapter 23 subdirectory.
Problems with Classic ASP
While many successful websites have been created using classic ASP, this architecture is not without its downsides. Perhaps the biggest downfall of classic ASP is the same thing that makes it a powerful platform: server-side scripting languages. Scripting languages such as VBScript and JavaScript are interpreted, typeless entities that do not lend themselves to robust OO programming techniques.
Another problem with classic ASP is the fact that an *.asp page does not yield very modularized code. Given that ASP is a blend of HTML and script in a single page, most ASP web applications are a confused mix of two very different programming techniques. While it is true that classic ASP allows you to partition reusable code into distinct include files, the underlying object model does not support true separation of concerns. In an ideal world, a web framework would allow the presentation logic (i.e., HTML tags) to exist independently from the business logic (i.e., functional code).
A final issue to consider here is the fact that classic ASP demands a good deal of boilerplate, redundant script code that tends to repeat between projects. Almost all web applications need to validate user input, repopulate the state of HTML widgets before emitting the HTTP response, generate an HTML table of data, and so forth.
Major Benefits of ASP.NET 1.x
The first major release of ASP.NET (version 1.x) did a fantastic job of addressing each of the limitations found with classic ASP. In a nutshell, the .NET platform brought about the following techniques:
•ASP.NET 1.x provides a model termed code-behind, which allows you to separate presentation logic from business logic.
•ASP.NET 1.x pages are compiled .NET assemblies, not interpreted scripting languages, which translates into much faster execution.
•Web controls allow programmers to build the GUI of a web application in a manner similar to building a Windows Forms application.
•ASP.NET web controls automatically maintain their state during postbacks using a hidden form field named __VIEWSTATE.


842 CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS
Table 23-1. ASP.NET Web-centric Namespaces
Namespaces |
Meaning in Life |
System.Web |
Defines types that enable browser/web server communication |
|
(such as request and response capabilities, cookie manipulation, |
|
and file transfer) |
System.Web.Caching |
Defines types that facilitate caching support for a web application |
System.Web.Hosting |
Defines types that allow you to build custom hosts for the |
|
ASP.NET runtime |
System.Web.Management |
Defines types for managing and monitoring the health of an |
|
ASP.NET web application |
System.Web.Profile |
Defines types that are used to implement ASP.NET user profiles |
System.Web.Security |
Defines types that allow you to programmatically secure your site |
System.Web.SessionState |
Defines types that allow you to maintain stateful information on |
|
a per-user basis (e.g., session state variables) |
System.Web.UI |
Define a number of types that allow you to build a GUI front end |
System.Web.UI.WebControls |
for your web application |
System.Web.UI.HtmlControls |
|
|
|
The ASP.NET Web Page Code Model
ASP.NET web pages can be constructed using one of two approaches. You are free to create a single *.aspx file that contains a blend of server-side code and HTML (much like classic ASP). Using the single-file page model, server-side code is placed within a <script> scope, but the code itself is not script code proper (e.g., VBScript/JavaScript). Rather, the code statements within a <script> block are written in your managed language of choice (C#, Visual Basic .NET, etc).
If you are building a page that contains very little code (but a good deal of HTML), a single-file page model may be easier to work with, as you can see the code and the markup in one unified *.aspx file. In addition, crunching your code and HTML into a single *.aspx file provides a few other advantages:
•Pages written using the single-file model are slightly easier to deploy or to send to another developer.
•Because there is no dependency between files, a single-file page is easier to rename.
•Managing files in a source code control system is slightly easier, as all the action is taking place in a single file.
The default approach taken by Visual Studio 2005 (when creating a new website solution) is to make use of a technique termed code-behind, which allows you to separate your programming code from your HTML presentation logic using two distinct files. This model works quite well when your pages contain significant amounts of code or when multiple developers are working on the same website. The code-behind model offers a few additional benefits as well:
•Because code-behind pages offer a clean separation of HTML markup and code, it is possible to have designers working on the markup while programmers author the C# code.
•Code is not exposed to page designers or others who are working only with the page markup (as you might guess, HTML folks are not always interested in viewing reams of C# code).
•Code files can be used across multiple *.aspx files.

CHAPTER 23 ■ ASP. NET 2 . 0 WEB PAGES AND WEB CONTROLS |
843 |
Regardless of which approach you take, do know that there is no difference in terms of performance. Also be aware that the single-file *.aspx model is no longer considered evil as proclaimed in .NET 1.x. In fact, many ASP.NET 2.0 web applications will benefit by building sites that make use of both approaches.
Working with the Single-File Page Model
First up, let’s examine the single-file page model. Our goal is to build an *.aspx file (named Default.aspx) that displays the Inventory table of the Cars database (created in Chapter 22). While you could build this page using nothing but Notepad, Visual Studio 2005 can simplify matters via IntelliSense, code completion, and a visual page designer.
To begin, open Visual Studio 2005 and create a new Web Form using the File New File menu option (see Figure 23-8).
Figure 23-8. Creating a new *.aspx file
Once the page loads into the IDE, notice that the bottom area of the page designer allows you to view the *.aspx file in two distinct manners. If you select the Design button, you are shown a visual designer surface that allows you to build the UI of your page much like you would build a Windows Form (drag widgets to the surface, configure them via the Properties Window, etc.). If you select the Source button, you can view the HTML and <script> blocks that compose the *.aspx file itself.
■Note Unlike earlier versions of Visual Studio, the Source view of Visual Studio 2005 has full-blown IntelliSense and allows you to drag and drop UI elements directly onto the HTML.
Using the Visual Studio 2005 Toolbox, select the Standard tab and drag and drop a Button, Label, and GridView control onto the page designer (the GridView widget can be found under the Data tab of the Toolbox). Feel free to make use of the Properties window (or the HTML IntelliSense) to set various UI properties and give each web widget a proper name via the ID property. Figure 23-9 shows one possible design (I kept my look and feel intentionally bland to minimize the amount of generated control markup).