
Pro CSharp 2008 And The .NET 3.5 Platform [eng]
.pdf
1172 CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES
Figure 31-7. The initial crack at the default.htm page
The Role of Client-Side Scripting
In addition to HTML UI elements, a given *.htm file may contain blocks of script code that will be emitted into the response stream and processed by the requesting browser. There are two major reasons why client-side scripting is used:
•To validate user input in the browser 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 (termed 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 supplying data within a required field), you can alert the user to 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!).

CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES |
1173 |
■Note Do be aware that even when performing client-side validation (for improved response time), validation should also occur on the web server itself. This will help ensure that the data has not been tampered with as it was sent across the wire. As explained in the following chapter, the ASP.NET validation controls will automatically perform clientand server-side validation.
In addition to validating user input, client-side scripts can also be used to interact with the underlying object model (the DOM) of the web 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 ones are VBScript and JavaScript. VBScript is a subset of the Visual Basic 6.0 programming language. Be aware that Microsoft Internet Explorer is the only web browser that has built-in support for client-side VBScript support (other browsers may or may not provide optional plug-ins). 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 it 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 scriptlike 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 additional HTML button (btnHelp) to your default.htm page that allows the user to view help information. To capture the Click event for this button, select btnHelp from the upper-left drop-down list of the HTML form designer and select the onclick event from the right drop-down list. This will add an onclick attribute to the definition of the new Button type:
<input id="btnHelp" type="button" value="Help" language="javascript" onclick="return btnHelp_onclick()" />
Visual Studio 2008 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:

1174 CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES
<script language="javascript" type="text/javascript">
// <!CDATA[
function btnHelp_onclick() {
alert("Dude, it is not that hard. Click the Submit button!");
}
// ]]>
</script>
Note that the scripting block has been wrapped within a CDATA section. The reason for this 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 like 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, save your work. You can open your browser of choice, 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
If you click the Help or Submit button, you should find the correct message box launched by your browser of choice. Do notice that if you enter some random data into your text boxes, you will not see the validation error displayed when you do click the Submit button.
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) 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:

CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES |
1175 |
<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 is 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=Foo$&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 a server-side script using a small set of COM objects and a bit of elbow grease. 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 illustrates the basic operation of the request/response cycle). 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 2008 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 follows:
<%@ 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>

1176 CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES
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 serverside 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, etc.) 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.
At this point be sure to save each of your web files. 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, as you see in Figure 31-8.
Figure 31-8. The dynamically generated HTML
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:
<body>
<h1 align="center">Here is what you sent me:</h1> <P align="center">
<b>User Name: </b>
<%= Request.Form("txtUserName") %> <br>

CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES |
1177 |
<b>Password: </b>
<%= Request.Form("txtPassword") %> <br> </P>
</body>
That wraps up our web-centric primer. Hopefully, if you’re new to web development you now have a better understanding of the basic building blocks of a web-based application. However, before we check out how the ASP.NET web platform improves upon the current state of affairs, let’s take a brief moment to critique classic ASP and understand its core limitations.
■Source Code The ClassicAspCars project is included under the Chapter 31 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 downside 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 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 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 to the Microsoft web development paradigm:
•ASP.NET provides a model termed code-behind, which allows you to separate presentation logic from business logic.
•ASP.NET pages are coded using .NET programming languages, rather than interpreted scripting languages. The code files are compiled into valid .NET assemblies (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/WPF application.
•ASP.NET web controls automatically maintain their state during postbacks using a hidden form field named __VIEWSTATE.
•ASP.NET web applications are completely object-oriented and make use of the Common Type System (CTS).
•ASP.NET web applications can be easily configured using standard IIS settings or using a web application configuration file (Web.config).

1178 CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES
Major Enhancements of ASP.NET
While ASP.NET 1.x was a major step in the right direction, ASP.NET 2.0 provided additional bells and whistles. Consider this partial list:
•Introduction of the WebDev.WebServer.exe testing web server
•A large number of additional web controls (navigation controls, security controls, new data controls, new UI controls, etc.)
•The introduction of master pages, which allow you to attach a common UI frame to a set of related pages
•Support for themes, which offer a declarative manner to change the look and feel of the entire web application
•Support for Web Parts, which can be used to allow end users to customize the look and feel of a web page
•Introduction of a web-based configuration and management utility that maintains your
Web.config files
Major .NET 3.5 Web Enhancements
As you would expect, .NET 3.5 further increases the scope of the ASP.NET programming model. Perhaps most important, we now have
•New controls to support Silverlight development (recall that this is a WPF-based API for designing rich media content for a website)
•Integrated support for Ajax-style development, which essentially allows for “micropostbacks” to refresh part of a web page as quickly as possible
Given that this book is not focused exclusively on web development, be sure to consult the
.NET Framework 3.5 documentation for details of topics not covered here. The truth of the matter is that if I were to truly do justice to every aspect of ASP.NET, this book would easily double in size. Rest assured that by the time you complete this section of the text, you will have a solid ASP.NET foundation to build upon as you see fit.
■Note If you require a comprehensive examination of ASP.NET, I suggest picking up a copy of Pro ASP.NET 3.5 in C# 2008, Second Edition by Matthew MacDonald (Apress, 2007).
The ASP.NET Namespaces
As of .NET 3.5, there are well over 30 web-centric namespaces in the base class libraries. From a high level, these namespaces can be grouped into several major categories:
•Core functionality (e.g., types that allow you to interact with the HTTP request and response, Web Form infrastructure, theme and profiling support, Web Parts, security, etc.)
•Web Form and HTML controls
•Mobile web development
•Silverlight development

CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES |
1179 |
•Ajax development
•XML web services
Table 31-1 describes several of the core ASP.NET namespaces.
Table 31-1. The Core 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/JScript). Rather, the code statements within a <script> block are written in your .NET language of choice (C#, Visual Basic, 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, placing your procedural code and HTML markup 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 2008 (when creating a new website solution) is to make use of a technique known as 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 a significant amount of code or when multiple developers are working on the same website. The code-behind model offers several benefits as well:

1180 CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES
•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.
Regardless of which approach you take, do know that there is no difference in terms of performance. In fact, many ASP.NET web applications will benefit by building sites that make use of both approaches.
Building a Data-Centric Single-File Test Page
First up, let’s examine the single-file page model. Our goal is to build an *.aspx file that displays the Inventory table of the AutoLot database (created in Chapter 22). While you could build this page using nothing but Notepad, Visual Studio 2008 can simplify matters via IntelliSense, code completion, and a visual page designer.
To begin, open Visual Studio 2008 and create a new Web Form using the File New File menu option (see Figure 31-9). Once you have done so, save this file (with the name Default.aspx) under a new directory on your hard drive named C:\CodeTests\SinglePageModel.
Figure 31-9. Creating a new *.aspx file
Manually Referencing AutoLotDAL.dll
Next, use Windows Explorer to create a subdirectory under the SinglePageModel folder named “bin”. The specially named bin subdirectory is a registered name with the ASP.NET runtime engine. Into the \bin folder of a website’s root, you are able to deploy any private assemblies used by the web application. For this example, place a copy of AutoLotDAL.dll (see Chapter 22) into the C:\CodeTests\SinglePageModel\bin folder.

CHAPTER 31 ■ BUILDING ASP.NET WEB PAGES |
1181 |
■Note As shown later in this chapter, when you use Visual Studio 2008 to create a full-blown ASP.NET web application, the IDE will maintain the \bin folder on your behalf.
Designing the UI
Now, using the Visual Studio 2008 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 31-10 shows one possible design. (I kept the example’s look and feel intentionally bland to minimize the amount of generated control markup, but feel free to spruce things up to your liking.)
Figure 31-10. The Default.aspx UI
Now, locate the <form> section of your page. Notice how each web control has been defined using an <asp:> tag. Before the closing tag, you will find a series of name/value pairs that correspond to the settings you made in the Properties window:
<form id="form1" runat="server"> <div>
<asp:Label ID="lblInfo" runat="server" Text="Click on the Button to Fill the Grid">
</asp:Label> <br />
<br />
<asp:GridView ID="carsGridView" runat="server"> </asp:GridView>
<br />
<asp:Button ID="btnFillData" runat="server" Text="Fill Grid" /> </div>
</form>