<asp:TextBox> Control
In order to become processors and providers of information, Web pages require data for input to
their scripts. The sources for most of the input to scripts are the collections of data stored in
files and databases. Another important source, however, is the user. Users supply input data that
is processed in some fashion to return information output. Users also make choices to control
processing actions.
There are several ways in which users can provide data and choices to scripts using various Web
form controls. You probably are familiar with textboxes, radio buttons, checkboxes, and drop-down
lists. Beginning with this tutorial you are introduced to these types of controls, how to create
them on a Web page, and how to devise scripts to process the input data they supply.
Textbox Input and Output
A textbox is probably the most popular mechanism for soliciting user input. It is a boxed
area into which the user types information for server processing. It is normally accompanied by
a button to call a subprogram to process the entered data. The following textbox is typical.
After entering any text into this input area, click the "Submit" button. A subprogram is called
to display the contents of the textbox.
Figure 6-1. A typical textbox to solicit user input.
A textbox also can be a target area for script output. In the following example, the entered
data is reported in the textbox itself.
Figure 6-2. A textbox used as both an input and output area.
Format for TextBox Control
A textbox is placed on a Web page by coding the <asp:TextBox>
control. The TextBox can be sized to any dimensions and can serve as either a data input area or
a script output area. Its general format is shown below.
Figure 6-3. General format for <asp:TextBox> control.
The Text property is a reference to the value appearing in the
controlthe data entered by the user or the value displayed by a script. An initial value can
be displayed in the TextBox by coding this attribute; otherwise, the TextBox is initially blank. The
width of the TextBox can be set with the Columns property giving
the approximate number of characters to display. The maximum number of typed characters allowed is
set with the MaxLength property.
By default, a TextBox is a single-line entry box. Multiple lines of text are permitted
with the TextMode="MultiLine" setting; the number of lines to
display is given in the Rows property. For a multiline TextBox,
the entry is automatically wrapped unless the Wrap property is
set to False. With a specification of
TextMode="Password", the TextBox displays as a single-line entry box, and entered
characters are echoed as bullets for privacy. A password TextBox cannot be prefilled with
Text characters.
Although normally used as an input area, a TextBox also can serve as a target for
script output. In these cases, you may not want the user to be able to edit the output. So,
the ReadOnly property can be set to "True"
to disallow changes to the displayed information.
Usually, TextBoxes are accompanied by buttons to call subprograms to process the entered data.
However, the TextBox itself can be configured to call a subprogram. Its
AutoPostBack="True" setting automatically posts back to the server
when its content changes and the user tabs from or clicks outside the control. The subprogram
named in the OnTextChanged property is called.
Creating TextBox Controls
The following examples demonstrate various <asp:TextBox> settings.
Text entered into a TextBox is displayed in an accompanying <asp:Label>
control when the "Submit" button is clicked. Notice that submitted text reappears in the
TextBoxes as a result of the page maintaining its View State and repopulating the control. TextBox
entries can be cleared between page postings by including script code to assigned a null character
("") to the textbox. The script used for the following example TextBoxes is coded as shown below.
<SCRIPT Runat="Server">
Sub ShowText (Src As Object, Args As EventArgs)
Output.Text = Input.Text
End Sub
</SCRIPT>
Listing 6-1. Script for example TextBoxes in Figure 6-4.
Figure 6-4. Varieties of TextBox controls.
For this last example using the AutoPostBack feature, the
called subprogram ShowText has the same signature as a subprogram
called by a Button.
The above TextBoxes use default stylings except for specified sizes given for the controls.
You can, though, decorate a TextBox using the full range of server and CSS style settings. The
following example TextBox has an assortment of styles.
Figure 6-5. A styled TextBox control.
Scripting TextBoxes
TextBoxes supply input data for scripts. The idea is for scripts to respond to user requests, taking
actions to personalize the output for whatever input is submitted. There are, of course, inummerable
ways in which user data can be processed. These ways are investigated throughout the tutorials. As a
simple initial example, the following form permits users to enter width and height dimensions for a
rectangle. The script calculates the resulting area of the rectangle and draws it on the screen.
Initial width and height values are supplied; click the "=" button to view the results.
Figure 6-6. Creating a rectangle from TextBox input.
<%@ Import Namespace="System.Drawing" %>
<SCRIPT Runat="Server">
Sub Make_Rectangle (Src As Object, Args As EventArgs)
If IsNumeric(Width.Text) AND IsNumeric(Height.Text) Then
Area.Text = FormatNumber(Width.Text * Height.Text, 0)
Rectangle.Width = Unit.Parse(Width.Text)
Rectangle.Height = Unit.Parse(Height.Text)
Rectangle.BorderStyle = BorderStyle.Solid
Rectangle.BorderWidth = Unit.Parse("1px")
Rectangle.BackColor = Color.FromName("#FF6666")
End If
End Sub
</SCRIPT>
<form Runat="Server">
<h3>Make a Rectangle:</h3>
<table border="0" cellpadding="0">
<tr style="text-align:left">
<th colspan="2">Width</th>
<th colspan="2">Height</th>
<th>Area</th>
</tr>
<tr>
<td><asp:TextBox id="Width" Runat="Server"
Columns="1"
MaxLength="3"
Text="100"
Style="text-align:right"/>
</td>
<td>x</td>
<td><asp:TextBox id="Height" Runat="Server"
Columns="1"
MaxLength="3"
Text="100"
Style="text-align:right"/>
</td>
<td><asp:Button Runat="Server"
Text=" = "
OnClick="Make_Rectangle"/>
</td>
<td><asp:TextBox id="Area" Runat="Server"
Columns="3"
ReadOnly="True"
Style="text-align:right"/>
</td>
</tr>
</table>
<p><asp:Panel id="Rectangle" Runat="Server"/></p>
</form>
Listing 6-2. Code to produce a rectangle from TextBox entry.
An XHTML table is used to arrange the display of text and boxes and plays no real part in the
processing. The two input TextBox controls (id="Width" and
id="Height") provide the input areas for entering the dimensions of the rectangle. They are
given initial values and are restricted to a maximum of three characters to restrict the display
size of the rectangle.
When the button is clicked, the Make_Rectangle subprogram is called.
Since calculating the area of the rectangle requires numeric values to be entered, a check is
made that both the Width and Height input
values are numbers (using the Visual Basic IsNumeric() function), and
the script is run only if this is the case.
The TextBox id="Area" stores the results of multiplying
the input width by the input height. Its ReadOnly property
is set to "True" to keep users from changing the displayed results. Even
though TextBoxes, as the name implies, represent values as text strings, the multiplication
operation converts the strings to numbers in order to perform the operation. You can explicitly
make this conversion using the Visual Basic CInt(Width.Text) and
CInt(Height.Text) conversions.
The script draws the resulting rectangle by formatting an <asp:Panel>
control. Formatting the Panel is a simple matter of styling it with server properties for
which the System.Drawing namespace is imported to the page.
Since Textboxes permit free-form user input, it is usually necessary to edit or validate entered
data to make sure it conforms to script expectations. Various methods of data editing are covered
throughout the tutorials.
User Login
A popular use of TextBox controls is to create login forms for restricting access to Web
pages to users who have valid accounts and/or know correct passwords. The following example
shows a login form for access to this tutorial page (even though you already have arrived
here). If you enter the correct password ("xyzzy"), this page is
reloaded. If you enter a blank or incorrect password, this page is not reloaded and an error
message is displayed. The account entry is not tested.
Account:
Password:
Figure 6-7. A login form.
<SCRIPT Runat="Server">
Sub Log_In (Src As Object, Args As EventArgs)
If Password.Text = "xyzzy" Then
Response.Redirect("aspnet06-01.aspx")
Else
Message.Text = "Incorrect password"
End If
End Sub
</SCRIPT>
<form Runat="Server">
<asp:Panel Runat="Server"
BorderStyle="Ridge"
BorderWidth="5px"
Width="275px"
Height="120px"
Style="padding:20px">
Account:
<asp:TextBox id="Account" Width="100px" Runat="Server"/><br/>
Password:
<asp:TextBox id="Password" TextMode="Password" Width="100px"
Runat="Server"/>
<asp:Button Text="Login" OnClick="Log_In" Runat="Server"/><br/>
<asp:Label id="Message" EnableViewState="False" ForeColor="#FF0000"
Runat="Server"/>
</asp:Panel>
</form>
Listing 6-3. Code for login form.
Notice that the valid password is hard-coded in the script. This may seem risky and susceptible
to unwanted viewing. Remember, however, that server script cannot be viewed in the source listing
of the page. Therefore, the coded password is not viewable from within the browser.
Restricting Site Access
It is often the case that a login form is used to restrict access to an entire Web site, not
just to a single page. An addition to the above script can handle this situation. It requires setting
an indicator, or a flag, that can be tested on every Web page to check whether a valid login
has occured.
Recall that a Session variable is a global variable that is accessible by any page in the
current Web directory. By setting a Session variable in the login script to indicate that the
visitor has logged in, all pages can check this variable to determine whether or not to permit
access to the page. Below is a rewrite of the previous script to set a Session
variableSession("LoggedIn")indicating successful login.
Assume this script appears on a login page, say Login.aspx, that
displays a form similar to the one shown above.
<SCRIPT Runat="Server">
Sub Log_In (Src As Object, Args As EventArgs)
If Password.Text = "xyzzy" Then
Session("LoggedIn") = True
Else
Message.Text = "Incorrect password"
End If
End Sub
</SCRIPT>
Listing 6-4. Script using Session variable to indicate successful login.
Since Session("LoggedIn") is globally accessible, all pages that need
to restrict access can test this variable. If it has been set to True,
then access is permitted; if it has not been set to True, then access
is not permitted, in which case redirection can be made back to the login page.
The following script needs to appear on every page to which access is restricted. When the
page loads, Session("LoggedIn") is tested. If its value is not
True, then redirection is immediately to the Login.aspx
page where the form is displayed. If its value is True, then
redirection does not take place and the page is loaded for viewing. This script is required on
every restricted page; otherwise, access to the page would be successful simply by entering its
URL in the browser, skipping the login page altogether.
<SCRIPT Runat="Server">
Sub Page_Load
If Session("LoggedIn") <> True Then
Response.Redirect("Login.aspx")
End If
End Sub
</SCRIPT>
Listing 6-5. Script to test for successful login.
Recall that Session variables remain "alive" for 20 minutes following the last access to a page
in the current Web directory. If the user is idle for longer that 20 minutes, then the Session
variable becomes null and access to any page ends up back at the login page.
Maintaining User Accounts
In the previous examples, only a password is tested for page and site access. Usually, in addition
to a password, a user account is checked. Normally, user accounts are maintained in a database,
along with private passwords that correspond with the accounts. The following Access database
table shows a typical layout of account records. This Accounts table is
in a UserAccounts.mdb database. It could be part of any database depending
on the organization of your site.
| Field Name |
Data Type |
Field Size |
Example Data |
| TheAccount |
Text |
8 |
aaaa1111 |
| ThePassword |
Text |
8 |
secret |
Figure 6-8. Accounts table of UserAccounts.mdb database.
There are two techniques to check for matching accounts and passwords in the database, both
of which involve checking for a returned recordset from an SQL query.
Using the HasRows Property
You should recall from previous discussions that the DataReader has a
HasRows property that can be tested for the return of a recordset. If, then,
a SELECT statement attempts to locate a user account record with
particular account and password values in its fields, its existence is confirmed by the
DataReader's HasRows property value of True. This technique is
used in the following script which assumes an account and password data entry form similar
to the one in Figure 6-7 with id="Account" and
id="Password" TextBoxes.
<%@ Import Namespace="System.Data.OleDb" %>
<SCRIPT Runat="Server">
Sub Log_In (Src As Object, Args As EventArgs)
Dim DBConnection As OleDbConnection
Dim DBCommand As OleDbCommand
Dim DBReader As OleDbDataReader
Dim SQLString As String
DBConnection = New OleDbConnection( _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Server.MapPath("../Databases/UserAccounts.mdb"))
DBConnection.Open()
SQLString = "SELECT * FROM Accounts " & _
"WHERE TheAccount = '" & Account.Text & "' " & _
"AND ThePassword = '" & Password.Text & "'"
DBCommand = New OleDbCommand(SQLString, DBConnection)
DBReader = DBCommand.ExecuteQuery()
If DBReader.HasRows Then
Session("LoggedIn") = True
Else
Message.Text = "Incorrect account or password"
End If
DBReader.Close()
DBConnection.Close()
End Sub
</SCRIPT>
Listing 6-6. Script to test login entries against database using DataReader's HasRows property.
The fact that the HasRows property is True
means that a matching record was found. It is not necessary to access or refer to the
individual data fields in the record. Of course, a Page_Load
script needs to be added to each restricted page to check the Session variable for valid login.
Using the SQL Count(*) Function
The SQL language has a Count(*) function that returns the
number of records in a returned recordset. By testing this count you can determine whether or
not a match was made during a query for an account and password.
<%@ Import Namespace="System.Data.OleDb" %>
<SCRIPT Runat="Server">
Sub Log_In (Src As Object, Args As EventArgs)
Dim DBConnection As OleDbConnection
Dim DBCommand As OleDbCommand
Dim SQLString As String
Dim RecordCount As Integer
DBConnection = New OleDbConnection( _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Server.MapPath("../Databases/UserAccounts.mdb"))
DBConnection.Open()
SQLString = "SELECT Count(*) FROM Accounts " & _
"WHERE TheAccount = '" & Account.Text & "' " & _
"AND ThePassword = '" & Password.Text & "'"
DBCommand = New OleDbCommand(SQLString, DBConnection)
RecordCount = DBCommand.ExecuteScalar()
If RecordCount <> 0 Then
Session("LoggedIn") = True
Else
Message.Text = "Incorrect account or password"
End If
DBConnection.Close()
End Sub
</SCRIPT>
Listing 6-7. Script to test login entries against database using the SQL Count(*) function.
When database access returns a record count it is not necessary to create a DataReader
to iterate a recordset. In fact, no recordset is returned. Instead, the Command object's
ExecuteScalar() method (rather than its
ExecuteQuery() method) is used to return a single record count value, which in this case
is assigned to variable RecordCount.
RecordCount = DBCommand.ExecuteScalar()
Listing 6-8. Capturing a record count of matching records.
If the record count is not 0 (RecordCount <> 0), then the Session
variable is set to indicate successful login. Again, a Page_Load
script needs to be added to each restricted page to check the Session variable for valid login.
Incidentally, it is not necessary to store the record count in a separate variable and then test
the variable. These steps can be combined as follows by directly testing the results of the
ExecuteScalar() method.
If DBCommand.ExecuteScalar() <> 0 Then
Session("LoggedIn") = True
Else
Message.Text = "Incorrect account or password"
End If
Listing 6-9. Testing a record count of matching records.
Returning Single Database Values
The ExecuteScalar() method is an efficient way to return a single value
from a database query. As well as returning a record count, it can be used to return the value
from a single data field. For instance, assume you want to retrieve only the
Password field for a single matching record from the Accounts
table. The following code can be used.
Sub Get_Password (Src As Object, Args As EventArgs)
Dim DBConnection As OleDbConnection
Dim DBCommand As OleDbCommand
Dim SQLString As String
Dim Password As String
DBConnection = New OleDbConnection( _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & System.MapPath("../Databases/UserAccounts.mdb"))
DBConnection.Open()
SQLString = "SELECT ThePassword FROM Accounts WHERE Account = 'aaaa1111'"
DBCommand = New OleDbCommand(SQLString, DBConnection)
Password = DBCommand.ExecuteScalar()
DBConnection.Close()
End Sub
Listing 6-10. Returning a single data value from a database query.
As the completion of this subprogram, ThePassword value from the
database table is stored in variable Password. It is not necessary
to create and iterate a DataReader to retrieve a single value.
In some of the previous examples, TextBox controls are used to solicit user input that is applied
against a database. TextBoxes present vulnerabilities that invalid data entered by the user can
abort execution of scripts, or in the worse case, be the unwitting sources of intentionally
malicious code that can easily destroy an entire database. Protection against these vulnerabilities
is discussed under "Validation Controls."