An application is defined as the set of files in an IIS virtual directory and its subdirectories. The files that constitute an ASP.NET application typically include:
•A Global.asax file containing application-level program directives, handlers for application and session-level events, and declarations of objects that are globally accessible to all parts of the application.
•A Config.web file containing configuration information.
•One or more ASPX files containing Web Forms.
•One or more code files written in C# containing the application's code.
Code files aren't always present in the virtual directory because code can optionally be placed in the ASPX files. But most Web Forms applications especially those created with Visual Studio.NET segregate code and data into separate files
Global.asax is to ASP.NET what Global.asa is to ASP. If you want to trap events such as Application_Start, Application_End, Session_Start, and Session_End (which are fired when applications start and stop and sessions begin and end) you put the event handlers in Global.asax. Typical uses for these event handlers include initializing state for each user and manipulating program counters. Config.web is new to ASP.NET. It's an XML-formatted file that stores an application's configuration settings. It's a welcome improvement over ASP, whose insistence on storing configuration data in the IIS metabase makes moving an application from one machine to another a chore. Plus, because it's a text file, Config.web can be edited with a text editor like Notepad.
Application Pages
Each ASPX file included in a Web Forms application constitutes one page of the application. The first time a page is requested, ASP.NET dynamically generates a class to represent that page by deriving from System.Web.UI.Page. After compiling the derived class and caching the compiled executable in a special directory (so subsequent requests for the same page will execute much faster), ASP.NET instantiates the class and executes it to generate HTML to return to the client.
The HTML included in the output stream comes from the HTML present in the ASPX file, the page's controls, and any scripts that write out HTML of their own. After it's executed, the instance of the page object is discarded. Thus, a page object's lifetime lasts from the time it's instantiated following each new request, until the request is complete.
During its lifetime, a page undergoes several distinct phases. As it enters each new phase, the page fires an event that can be processed with a server-side script. For Web Forms developers, the most important page-level event is Page_Load, which is called each time the page is instantiated. Because Page_Load is called before the page is rendered to the client, it's a great place to perform any one-time initializations that need to happen before rendering takes place. Developers can respond to Page_Load events by implementing a handler in a script:
A common use for Page_Load events is to query a database for information needed to initialize one or more of the page's controls. Page_Load can even be used to populate the page with controls programmatically.
Because ASPX scripts execute in the context of a class derived from System.Web.UI.Page, they can call System Web.UI.Page methods and access System.Web.UI.Page properties. Those properties include Request, Response, Server, Application, and Session, which provide access to the ASP objects of the same name.
The Page class also exposes a Boolean property named IsPostBack that's often used by Page_Load handlers. In many cases, initializations performed in Page_Load only need to happen when the page is requested anew, not during postbacks. IsPostBack tells you whether your code is executing within a postback (IsPostBack==true) or in response to a new request (IsPostBack==false). The following Page_Load handler initializes a control with the results from a database query, but only if it's called outside of a postback:
Such code is often used to avoid requerying a database (and reinitializing a form's controls) when postbacks occur.
Page-level Directives
For the most part, the component of ASP.NET that compiles pages into executable form the page compiler does its work behind the scenes and without any input from you. However, you can add your two cents to the settings that it uses by including page-level directives in your ASPX files. The syntax for page-level directives is:
For example, including the following directive at the top of an ASPX file turns tracing on.
Tracing is a handy debugging aid that enables Web Forms to write trace output to Web pages. Similarly, the following statement enables tracing and identifies C# as the default language for scripts embedded within the page.
For a complete description of all the options that ASP.NET places at your disposal through page-level directives, consult the document titled " ASP.NET Page Syntax".
In some cases, page-level directives are optional. In certain scenarios, however, they're very much required. Web Forms that use custom controls, for example, require Register directives to define tag prefixes for those controls.
Separating Code and Data
One feature that's made accessible by page-level directives is code-behind, which enables Web Form code and data to be placed in separate files you can separate the two by moving the code to a CS file
Controls
The .NET Framework class library, which provides the classes common to all .NET applications, contains several classes that represent server controls. These classes are divided into two categories: HTML controls and Web controls.
HTML controls are created from classes in the .NET Framework class library's System.Web.UI.HtmlControls namespace. All HTML control classes derive, either directly or indirectly, from System.Web.UI.HtmlControls.HtmlControl. HTML control classes are instantiated by adding RunAt="server" to ordinary HTML tags. For example, the following statement declares a standard HTML text input field.
But this statement declares an instance of HtmlInputText.
Within an tag of this type, you can use standard HTML attributes such as Name and Value. You can also use attributes that map to the properties defined in the corresponding HTML control class. For example, the statement
assigns the value "UserName" to the HtmlInputText property named ID. This ID can be used to reference the control in server-side scripts. The following C# statement reads the text that the user entered into the control.
string strUserName = UserName.Value
documents all the HTML control classes and the HTML tags to which they correspond. These classes are provided primarily to ease the chore of migrating existing Web applications (particularly ASP applications) to ASP.NET. For example, rather than replacing all instances of with
HTML controls are little more than glorified wrappers around existing HTML tags, but Web controls are richer and more ambitious in scope. For example, you can use a Calendar control to display calendars in Web Forms and let users pick dates using a visual (and self-contained) UI. Some Web controls even adapt themselves to the browser that they're rendered to. For example, a RequiredFieldValidator control rendered to an uplevel browser includes client-side script that validates user input locally. The same control rendered to a browser that doesn't support scripting, however, uses round-trips to the server to flag blank fields.
The attributes that you can apply to tags when declaring Web controls are determined by the properties defined in the respective control classes. For example, because the TextBox class exposes properties named TextMode and Text, all of the following statements are valid:
The properties exposed by individual controls vary from control to control, but all Web controls, with the exception of Repeater, inherit a common set of properties from the base class WebControl.
Syntax is important when using these properties, particularly the Font, Width, Height, and XxxColor properties. The Font property has subproperties named Bold, Italic, Name, Names, Size, Strikeout, Underline, and Overline. To assign a value to a subproperty, separate the property name (Font) and the subproperty name with a hyphen, as in
The Font-Size property can be specified using pixels as the unit of measurement using either of the following syntactical conventions:
Or it can be expressed in points by replacing px with pt:
Width, Height, and BorderWidth values can be expressed in pixels, points, or percentages. Pixels is the default, so omitting px, pt, and % is the equivalent of writing out px.
Both HTML and Web controls support an event model that permits control events, such as pushbutton clicks, to be connected to server-side event handlers. You've seen one example of this already in below figure, where an OnClick attribute was used to connect the Calculate button to the OnCalculate method. The .NET SDK lists all the events defined by all the control types. In general, you can connect an event to a handler by prefixing the event name with On and using it as an attribute. For example, ListBox controls fire SelectedIndexChanged events each time the selection changes. The following statement connects SelectedIndexChanged events to a handler named OnNewSelection:
Note the parameter that sets AutoPostBack equal to True. To avoid unnecessary round-trips to the server, ListBox selection changes only prompt postbacks if AutoPostBack is True. In the absence of automatic postbacks, a server-side script will only see SelectedIndexChanged events when the form is posted back to the server in response to other stimuli. AutoPostBack is supported by CheckBox, CheckBoxList, DropDownList, ListBox, TextBox, RadioButton, and RadioButtonList controls. In every case, it defaults to False. Don't forget to toggle AutoPostBack on if you want to handle events from these control types. Also, be aware that AutoPostBack does nothing in downlevel browsers that don't support JavaScript.
Space constraints don't permit me to examine every one of the Web control classes in detail, but once you grasp the basics, the rest is easy to figure out. The following sections will give you a quick survey of the Web control classes in the .NET Framework class library and sample code showing how to use them in Web Forms applications.
Label Controls
Label controls, which are denoted by
To modify a Label control's text during the course of an application's execution, you can simply assign the control an ID and use a server-side script to write a new value to the control's Text property:
// In a C# script
HyperLink controls let you place hyperlinks (the equivalent of tags) in Web pages. Properties specific to HyperLink include Text, NavigateUrl, ImageUrl, and Target. Text specifies the control text, and NavigateUrl identifies the URL that the hyperlink points to.
If you'd like, you can replace Text with ImageUrl to display the hyperlink as an image instead of a text string:
You can use the Target property to reference a window or frame at the URL named by NavigateUrl. For example, adding a "Target=_new" attribute to an
Image Controls
Image controls are to Web Forms as tags are to HTML. Their purpose is to display images in Web pages. Control-specific properties include AlternateText, ImageAlign, ImageUrl, and Font. The following statement declares an Image control whose alternate text (the text displayed when the image file isn't available and when you mouse over the image) is "Company Logo" and whose appearance comes from Logo.jpg:
You can use the ImageAlign attribute to specify the image's alignment with respect to the text that surrounds it, and the Font property to change the font used for the alternate text.
TextBox Controls
TextBox controls are the Web Forms equivalent of and
Setting TextMode to "password" tells the control to act as a password control by displaying asterisks instead of characters:
The "multiline" setting creates a multiline text input field:
To read text from a TextBox control in a server-side script, simply read the control's Text property:
If the text in a TextBox has changed when the form is posted back to the server, the control fires a TextChanged event that can be handled by a script. The following example demonstrates how to synchronize the contents of a label control and a TextBox control by updating the label control each time a postback occurs. Note the AutoPostBack setting:
Be aware that TextChanged events are not fired each time a new character is typed into the TextBox. AutoPostBack="true" causes a postback to occur only when the TextBox loses the input focus after its contents are modified.
CheckBox and CheckBoxList Controls
CheckBox controls add checkboxes to Web pages. Useful CheckBox properties include Text, TextAlign, and Checked. The following statement creates an unchecked checkbox:
This one creates a checkbox that's checked and whose text is aligned to the left (rather than the right) of the checkbox:
To check the state of a checkbox from a server-side script, read the Checked property, which is a Boolean:
CheckBox controls fire CheckedChanged events when they're checked and unchecked. Use OnCheckedChanged to connect CheckedChanged events to a handler implemented in a server-side script. Also, don't forget to set AutoPostBack to True
The CheckBoxList control lets you display groups of checkboxes and exercise control over the group's layout. ListItem statements define the individual checkboxes within the group. Setting a ListItem's Selected property to True checks the corresponding checkbox:
Two CheckBoxList properties affect the layout of the checkboxes: RepeatColumns and RepeatDirection. RepeatColumns specifies the number of columns the checkboxes are to be divided into (default=1); RepeatDirection specifies whether the checkboxes are to be laid out in row-first order (RepeatDirection="horizontal") or column-first order (RepeatDirection="vertical"). Vertical is the default. Use the CellPadding and CellSpacing properties to fine-tune the spacing between checkboxes.
RadioButton and RadioButtonList Controls
RadioButton controls (
To programmatically determine whether a RadioButton is selected, read the button's Checked property. To trap notifications indicating that a RadioButton's state has changed, use the OnCheckChanged and AutoPostBack attributes.
RadioButtonList controls provide an alternate means for creating and grouping RadioButtons. The following code is equivalent to the previous code:
Note the lack of GroupName attributes. They're not needed with RadioButtonLists because grouping is implicit (each RadioButtonList constitutes its own group). Also be aware that like CheckBoxList controls, RadioButtonLists feature RepeatColumns and RepeatDirection properties that you can use to control the buttons' layout, as well as CellPadding and CellSpacing properties for tweaking their spacing. To find out which button in a RadioButtonList is selected, assign the RadioButtonList an ID and read its SelectedIndex property from a server-side script. SelectedIndex returns the zero-based index of the button that's selected.
ListBox and DropDownList Controls
ListBox and DropDownList controls are analagous to
These statements create a DropDownList containing the same items:
This server-side script, written in C#, modifies a pair of Label controls whose IDs are "Label1" and "Label2" to report which items were selected from the lists:
To permit a user to select multiple items from a listbox, add
In a derived class, you can use the SelectedIndices property that ListBox inherits from ListControl to identify the items selected in a multiple-selection ListBox. But because SelectedIndices is declared protected rather than public, you can't use it with an ordinary ListBox. (Note: In Beta 2, SelectedIndices will probably change from protected to internal, in which case it wouldn't even be available in classes derived from ListBox.) To read the selection from a multiple-selection ListBox, use the control's Items collection to enumerate the ListBox items and check each item's Selected property.
ListBoxes, DropDownLists, CheckBoxLists, and RadioButtonLists fire SelectedIndexChanged events upon the next server postback when the selection changes. You can add an OnSelectedIndexChanged attribute to a tag (for example,
Sometimes it's useful to fill list controls programmatically, based on information gathered at runtime. Here's one way to populate a ListBox from a server-side script:
And here's another wayâ€"one that utilizes System.Collections.ArrayList:
This sample works because ListBox and other ListControl-derived classes have properties named DataSource that can be initialized with a reference to any object that implements an ICollection interface, and because ArrayList and many other collection types provided by the .NET Framework class library implement ICollection. Calling the control's DataBind method tells the control to enumerate the collection's items and to bind them by displaying them. I'll have more to say about data binding in the section on list-bound controls later in this article.
Button, LinkButton, and ImageButton Controls
Three server controls Button, LinkButton, and ImageButton can be used to submit forms to the server to allow server-side processing to take place. All three control types do essentially the same thing; the difference is how they render themselves to the screen. Button controls resemble standard pushbuttons. LinkButtons look like hyperlinked text, and ImageButtons derive their looks from user-supplied images. When clicked, all three controls fire Command and Click events that can be handled in server-side scripts. In addition, ImageButtons transmit x and y coordinates revealing where in the image the click occurred.
All three classes expose properties named CommandArgument and CommandName that can be used to customize the information passed in Command events. In addition, Button and LinkButton expose their text through Text properties. ImageButton lacks a Text property but offers ImageUrl and ImageAlign properties instead.
The following code creates a Button and a LinkButton and connects them to a Click handler named OnSubmit:
An ImageButton can't be connected to the same Click handler as a Button or LinkButton because its Click event is prototyped differently: it receives an ImageClickEventArgs rather than an EventArgs. If the handler wants to know exactly where the click occurred, it can obtain the x and y coordinates from the ImageClickEventArgs:
The coordinates encapsulated in an ImageClickEventArgs are measured in pixels and are relative to the upper-left corner of the ImageButton.
Table Controls
Table controls (