Basic Page Design
ASP.NET pages normally are not static Web pages that display identical content
each time they are opened. Certainly, portions of these pages may display fixed content
hard-coded as text and XHTML much like standard Web pages. The usual situation, though, is one
requiring dynamic content, displaying information that changes in response to changing
user needs or to the changing status of the information itself.
Consider the page shown in Figure 2-25. When this page opens, a fixed heading and text paragraph
appear, unchanging from one page display to the next. A textbox and button are displayed for user
input. When the button is clicked, the page content changes. The name entered into the textbox
becomes part of a dynamically created welcome message that includes the current date and time.
Also, selected information is drawn from a database for display in a dynamically created table.
This page setup is fairly typical for ASP.NET pages. It includes fixed and dynamic content, the
latter generated by on-page scripts. It follows an input, processing, and output design model.
Figure 2-25. Producing dynamic content for a Web page.
ASP.NET Page Coding
When creating an ASP.NET page, it is best to consider first the XHTML code and server
controls needed to produce the final page display. In the above example, the results page is
composed of hard-coded text and XHTML for the unchanging text portions of the page, along with
five server controls to capture user input, to trigger script processing, to serve as display
targets for script output, and to link to a database to retrieve information for display. These
page components are coded as shown below.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Welcome Page</title>
</head>
<body>
<form Runat="Server">
<h2>Welcome to My Store</h2>
<p>Enter your name in the box below and click the button for our special
offers.</p>
Name: <asp:TextBox id="NameIn" Runat="Server"/>
<asp:Button Text="See Specials" OnClick="Display_Output" Runat="Server"/>
<p><asp:Label id="GreetingOut" Runat="Server"/></p>
<asp:AccessDataSource id="BookSource" Runat="Server"
DataFile="c:\eCommerce\Databases\BooksDB.mdb"
SelectCommand="SELECT BookID, BookName, BookPrice FROM Books
WHERE BookSale = True
ORDER BY BookID"/>
<asp:GridView id="BookGrid" DataSourceID="BookSource" Runat="Server"
Visible="False"/>
</form>
</body>
</html>
Listing 2-29. Code to produce dynamic content for a Web page.
The server controls used on this page are typical of the kinds of input, output, and
script activation controls that appear on many ASP.NET pages. Although these particular
controls are covered in more detail later, their general formats are summarized below so
you can begin coding your own ASP.NET pages.
The <form> Tag
As mentioned previously, the <body> of an ASP.NET page
includes a <form Runat="Server"> tag encompassing
all page content. Its general format is repeated below.
Figure 2-26. General format for <form> tag.
Pages are required to include this <form> tag any time there
is a call to a subprogram from a server control. Some pages may not require it; however, it is
a good idea to include this tag on all ASP.NET pages, whether required or not, just to
maintain the coding habit and to ensure that any type of control can be included on the page.
The <asp:TextBox> Control
Soliciting user input to a page often makes use of a textbox for entering information.
Under ASP.NET, a textbox is displayed with the <asp:TextBox>
control whose basic format is shown below.
Figure 2-27. General format for <asp:TextBox> control.
As is the case with all server controls, the Runat="Server" attribute
must be coded to make the TextBox accessible by server scripts. Also, an id
property is required for script references to the control in order to get or set its
contents and properties. The id can be any programmer-supplied
identification composed of alphabetic and numeric characters along with the underscore
( _ ) character. Blank spaces cannot appear in the
id value. In general, the id should be a recognizable name
suggestive of the contents of the TextBox.
A TextBox normally is displayed as an empty box for user input. However, it can optionally
display a text string by coding its Text property. This might be
used, for instance, to initially display an example response or to display a prompt for user input.
More importantly, since the Text property is a reference to the
contents of the TextBox, it is the property that is referenced in scripts to process input
from users who have entered data into the TextBox.
In the above example, an <asp:TextBox> control is coded in
its minimal configuration to produce an empty textbox for user input. An id
is supplied since a script needs to refer to this control to access the name entered into the box.
<asp:TextBox id="NameIn" Runat="Server"/>
Listing 2-30. Code for a minimally configured TextBox control.
The <asp:Label> Control
An <asp:Label> control defines an output area on the
page. It is a target area where scripts place output for display. It has no visible presence
except when text is assigned to the control. Its basic format is shown below.
Figure 2-28. General format for <asp:Label> control.
The control must include a Runat="Server" attribute for accessibility
from scripts; it also must be assigned an id identification for
script reference. Its Text property refers to the text characters
displayed through this control. These characters can include XHTML tags in order to format or
style the enclosed text.
The Label control used in the previous example contains minimal coding to identify it to a
script. Since no Text property is set for the control, it has no initial
value and no visible presence on the page. It serves as an output target, a "placeholder" on the
page where text appears when a script assigns output to the Text
property of the control.
<asp:Label id="GreetingOut" Runat="Server"/>
Listing 2-31. Code for a minimally configured Label control.
Although used here as an empty output area to await script assignment, a Label can display static text
by coding its Text property. This might be done, for instance, to display
an initial message on the page that is later replaced by a script-generated message.
The <asp:Button> Control
A way is needed for the user to trigger a script to write an output paragraph to the previous
Label control. A typical method is to create an <asp:Button>
control to call a subprogram to produce this output.
Figure 2-29. General format for <asp:Button> control.
An <asp:Button> control may or may not need an
id. An id is not required when the button is used only to
call a subprogram. If, on the other hand, the script needs to refer to the button, say to change its
styling or its text label as visual confirmation that the button was clicked, then an
id is required to identify this control to the script. In the present
example, the script has no need to reference the button, therefore there is no need for an
id.
<asp:Button Text="See Specials" OnClick="Display_Output" Runat="Server"/>
Listing 2-32. Code for a Button control.
A button's Text property provides the label displayed on the
button. Of course, the label assigned should have meaning to the user, suggestive of what happens
when the button is clicked.
The purpose of a Button control is to call a subprogram. This is done by coding an
OnClick event handler naming the subprogram to call when the
button is clicked. In this example, a subprogram named Display_Output
is called.
Incidentally, if you code only the XHTML, fixed text, and form controls for an ASP.NET page, and
the controls include a Button with an OnClick event handler, you will
generate a compiler error when the page is opened in the browser. This error is the result of not
having coded the subprogram named in the OnClick handler. If you just
want to view the layout of the page prior to adding the script, be sure to remove any
OnClick handlers. Then you can view the page layout. Later, after
adding the script portion of the page, replace the OnClick handlers.
The <asp:GridView> Control
Along with a greeting to the user, the example page displays a list of books and prices. This
list is presented as a table with three columns for the book ID, the book name, and the book price.
This information is drawn directly from a database table containing this and other information.
It comes from the Books table of the BooksDB.mdb
database that is used in examples throughout these tutorials.
Among the many ways to display information from external data sources is the
<asp:GridView> control. This control is designed especially for displaying
information from a database organized into rows and columns within a table. It has a great
assortment of property settings to control its layout and visual appearance; however, minimal
coding can produce a default table as used in this example. The general format for a GridView in
its default configuration is shown below.
Figure 2-30. General format for default <asp:GridView> control.
A GridView automatically displays as many columns as there are data fields retrieved from the
database; it displays as many rows as there are records returned from the database; it produces
column headings taken from the field names in the database. It presents this information in the
form of an XHTML table with collapsed borders.
<asp:GridView id="BookGrid" DataSourceID="BookSource" Runat="Server"
Visible="False" />
Listing 2-33. Code for a GridView control.
An id value is required only if the GridView is referenced
from a script. In the current example this is the case, so an id is
coded. In its full configuration, a GridView has numerous properties that can be set to control
its display. In the current example, its Visible property is
initially set to "False" so that the GridView does not appear on the
page until after user input is completed.
In order for a GridView to display database information, it must be associated with a
data source control. This control connects to the database and retrieves a set of records for
display. The data source control is bound to the GridView through the GridView's
DataSourceID property. In the current example, the property setting
DataSourceID="BookSource" points to this named data source control as the source of
the GridView's displayed information.
The <asp:AccessDataSource> Control
The data source control used to interface with Microsoft Access databases is the
<asp:AccessDataSource> control. Its general format to
retrieive a set of records from a database table is shown below.
Figure 2-31. General format for <asp:AccessDataSource> control.
The id assigned to the control must match that given in the
DataSourceID property of the display control for which this is the data
source. The DataFile property gives the server path to the
database; the SelectCommand property is an SQL
SELECT statement to retrieve a set of records from the database. This is all the information
needed to produce a recordset that can be bound to a GridView or to other output controls for
display of database information.
<asp:AccessDataSource id="BookSource" Runat="Server"
DataFile="c:\eCommerce\Databases\BooksDB.mdb"
SelectCommand="SELECT BookID, BookName, BookPrice FROM Books
WHERE BookSale = True
ORDER BY BookID"/>
Listing 2-34. Code for an AccessDataSource control.
In the current example, an AccessDataSource links to the BooksDB.mdb
database. This database is located on the server's c: drive in the
Databases subdirectory of the eCommerce
directory. An SQL SELECT statement retrieves three fields of information
from all records in the Books table where a book is on sale; the records
are returned in sorted order by the BookID field. In this example, seven
records are extracted from the table and made available through this control.
Binding a Data Source to a Control
When a page is first opened, the AccessDataSource immediately issues its
SelectCommand to retrieve the specified records from the database. This recordset is then
available for binding to any display control that identifies this data source in its
DataSourceID property. Binding involves displaying the data values
contained in the data source through a display control coded on the page. In this case, it is the
GridView that binds to the data source, formatting the returned recordset as a displayed table.
Although the example GridView is fully loaded and formatted for display when the page opens,
it should not be displayed until after the user enters a name and clicks the button. So, the
GridView's Visible property is initially set to
"False" to keep it hidden from view. It is revealed programmatically in the subprogram
that is called to display the welcome message.
At this point, all of the XHTML, fixed text, and server controls have been coded for the
page. All that remains is to code the script to make it all work.
ASP.NET Script Coding
The script portion of a page is coded at the top of the page, prefixed by any needed page
directives and enclosed inside <script> tags. This general outline
is fleshed out for the example page as shown in Listing 2-35. You might be surprised to see that
very little scripting is needed to animate the application. This is because much of the work is
behind the scenes, encapsulated inside server controls to save you from having to code
processing details. There is only one subprogram containing three Visual Basic statements needed
to perform all processing.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Page Language="vb" Debug="True" %>
<SCRIPT Runat="Server">
Sub Display_Output (Src As Object, Args As EventArgs)
If NameIn.Text <> "" Then
GreetingOut.Text = "Hello, <b>" & NameIn.Text & "</b>." _
& " Today is " & Format(DateString, "Long Date") _
& " and the time is " & Format(TimeString, "Long Time") & "." _
& " Check out our special prices on computer books listed" _
& " below:<br/>"
BookGrid.Visible = True
End If
End Sub
</SCRIPT>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Welcome Page</title>
</head>
<body>
<form Runat="Server">
<h2>Welcome to My Store</h2>
<p>Enter your name in the box below and click the button for our special
offers.</p>
Name: <asp:TextBox id="NameIn" Runat="Server"/>
<asp:Button Text="See Specials" On_Click="Display_Output" Runat="Server"/>
<p><asp:Label id="GreetingOut" Runat="Server"/></p>
<asp:AccessDataSource id="BookSource" Runat="Server"
DataFile="c:\eCommerce\Databases\BooksDB.mdb"
SelectCommand="SELECT BookID, BookName, BookPrice FROM Books
WHERE BookSale = True
ORDER BY BookID"/>
<asp:GridView id="BookGrid" DataSourceID="BookSource" Runat="Server"
Visible="False"/>
</form>
</body>
</html>
Listing 2-35. Script to produce dynamic content for a Web page.
A page directive is included at the top of the page giving the optional
Language specification and permitting Debug error messages to
appear at the developer's PC.
The Display_Output subprogram, being called by a button click, has
the necessary signature for a button-activated subprogram. Although no script reference is made to
the source (Src) object making the call or to any arguments
(Args) being passed, this signature still must be supplied for any
button-activated subprogram.
Script processing accomplishes two things. First, it produces the text welcome message integrating
the user's name from the TextBox; then it reveals the GridView table. Both of these actions are
contingent on the user entering a name; therefore, the script is enclosed inside a Visual Basic
If...End If decision structure to run only if a name is available in the
TextBox.
Sub Display_Output (Src As Object, Args As EventArgs)
If NameIn.Text <> "" Then
...rest of script
End If
End Sub
Listing 2-36. Testing for available input data.
Script references to properties of server controls follow common dotted notation practices;
that is, the id of the control is followed by a property name, separated by
a period.
Figure 2-32. General format for script references to control properties.
The script reference NameIn.Text refers to the value
(Text property) entered into the TextBox control
(id="NameIn") as user input. The If statement
tests this NameIn.Text property to ensure that it is not
empty, or null (NameIn.Text <> ""). With a name available, the script proceeds to
formulate the welcome message. This is a matter of producing a text string for assignment
to the Text property of the GreetingOut Label
control.
This output string is a concatenation of fixed text, the name from the TextBox, and a couple
of Visual Basic date and time properties formatted for display. The text string also includes XHTML
tags to assist in its formatting. The five lines of code are continuations of a single assignment
statement.
GreetingOut.Text = "Hello, <b>" & NameIn.Text & "</b>." _
& " Today is " & Format(DateString, "Long Date") _
& " and the time is " & Format(TimeString, "Long Time") & "." _
& " Check out our special prices on computer books listed" _
& " below:<br/>"
Listing 2-37. Concatenating a string for output display.
Finally, the script reveals the GridView table (id="BookGrid") by
settings its Visible property to True.
BookGrid.Visible = True
Listing 2-38. Revealing a hidden server control
The above example is a demonstration of the coding of and relationships between server
controls and script elements. It presents some common controls and their minimal coding, along
with typical ways in which scripts interact with these controls. It is not meant as full coverage
of the controls nor as definitive methods of coding subprograms. The example should, however,
give you a sense of the general approach to coding ASP.NET pages.
Scripting the Page_Load Event
The previous example is a common scenario where a user action causes a subprogram to run. It is
often the case, however, that scripts do not require user actions to invoke. They can be run
in response to events produced by the page itself. As mentioned previously, a common trigger for
scripts is the page's load event, when the page is accessed from server storage and loaded into
server memory prior to its transmittal to the requesting browser. The following page produces the
current date and time automatically each time the page loads, that is, when the page is
initially loaded by the server when the page first opens (the load event) and when
the page is reloaded by a button click (a post-back event). Full coding for this
application is shown below.
Welcome to My Page
Today is Sunday, February 05, 2012.
The time is 8:54:37 AM.
Figure 2-33. Producing dynamic content during page loading.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Page Language="vb" Debug="True" %>
<SCRIPT Runat="Server">
Sub Page_Load
DateOut.Text = Format(DateString, "Long Date")
TimeOut.Text = Format(TimeString, "Long Time")
End Sub
</SCRIPT>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Welcome Page</title>
</head>
<body>
<form Runat="Server">
<h2>Welcome to My Page</h2>
Today is <asp:Label id="DateOut" Runat="Server"/>.<br/>
The time is <asp:Label id="TimeOut" Runat="Server"/>.<br/>
<br/>
<asp:Button Text="Update Time" Runat="Server"/>
</form>
</body>
</html>
Listing 2-39. Code to produce dynamic content during page loading.
Two <asp:Label> controls are defined to receive script
output. These controls are surrounded by fixed text that does not change on loading and reloading
of the page. A button is provided to update the date and time. Notice that the button does not
include an OnClick event handler. It does not call a specific subprogram;
it merely causes the page to be reloaded.
Since the script should run each time the page loads, it is placed inside the special
Page_Load subprogram, so-named for this purpose. The subprogram
does not require an argument list since it is not explicitly called by an event handler.
The subprogram is run each time the page is opened to assign system date and time information
to the Label controls. It runs, then, the first time this page is accessed and each time the
button is clicked to reload the page.
Handling Post-Back Events
As noted, there are two distinct kinds of events that cause the Page_Load
subprogram to run. One event is an initial page load event, occuring the first
time a page is accessed, normally in response to a URL request for the page. The other event is
a page post-back event, a reloading of the page in response to a user event such as a mouse click.
It is sometimes important to differentiate between these two events in coding the
Page_Load subprogram.
Consider the following application. When this page is first loaded into server memory in
response to a URL request, the page is time-stamped in the Page_Load
subprogram with the date and time it was first accessed. It currently reports when you
first opened this page. This date and time should not change, though, even when the button click
causes a post-back event to reload the page and rerun the Page_Load
subprogram. The date and time should remain as initially reported even though time moves
forward.
Welcome to My Page
You first arrived at this page on
Sunday, February 05, 2012
at
8:54:37 AM.
Figure 2-34. Maintaining content on page post-back.
In clicking the above button you will notice that the date and time do not change, even
though their reporting appears in the Page_Load subprogram which is run
each time the button is clicked. The reason the date and time are not updated is because
the script differentiates between the first time the page is loaded and subsequent times the
page is loaded.
This Page_Load subprogram avoids updating the date and time by
testing for a post-back event. This is done by testing the page's IsPostBack
property.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Page Language="vb" Debug="True" %>
<SCRIPT Runat="Server">
Sub Page_Load
If Not Page.IsPostBack Then
DateOut.Text = Format(DateString, "Long Date")
TimeOut.Text = Format(TimeString, "Long Time")
End If
End Sub
</SCRIPT>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Welcome Page</title>
</head>
<body>
<form Runat="Server">
<h2>Welcome to My Page</h2>
You first arrived at this page on
<b><asp:Label id="DateOut" Runat="Server"/></b> at
<b><asp:Label id="TimeOut" Runat="Server"/></b>.
<p><asp:Button Text="Post Back" Runat="Server"/></p>
</form>
</body>
</html>
Listing 2-40. Code to maintain dynamic content on page post-back.
The Page.IsPostBack condition is True
when the page is reloaded due to a post-back event such as a button click to reload the
page or to call a subprogram. Therefore, the condition "Not Page.IsPostBack"
identifies the situation where the page is not posted back. The script is run, then, only
when the page is initially loaded. When the button click posts back the page, the script
is not run. You will notice, though, that if you reload this page from the tutorial menu
or if you refresh the page with the browser's Refresh button, a new date and time are reported.
In these cases the page is loaded anew, not posted back through a server control. As in the
previous example, the button click does not call a named subprogram; it just posts back the page
to cause the Page_Load subprogram to run.
The above examples are typical of the kinds of processing performed by ASP.NET pages. Although
these are relatively simple examples, they illustrate the common layout and coding of pages and
the sorts of processing requests they handle. Regardless of how complex page processing may appear,
it normally involves some combination of input controls, script activation controls, output
controls, data source controls, and information display controls arranged and activated in a
similar manner to those described above.