- •Table of Contents
- •Preface
- •What is ASP.NET?
- •Installing the Required Software
- •Installing the Web Server
- •Installing Internet Information Services (IIS)
- •Installing Cassini
- •Installing the .NET Framework and the SDK
- •Installing the .NET Framework
- •Installing the SDK
- •Configuring the Web Server
- •Configuring IIS
- •Configuring Cassini
- •Where do I Put my Files?
- •Using localhost
- •Virtual Directories
- •Using Cassini
- •Installing SQL Server 2005 Express Edition
- •Installing SQL Server Management Studio Express
- •Installing Visual Web Developer 2005
- •Writing your First ASP.NET Page
- •Getting Help
- •Summary
- •ASP.NET Basics
- •ASP.NET Page Structure
- •Directives
- •Code Declaration Blocks
- •Comments in VB and C# Code
- •Code Render Blocks
- •ASP.NET Server Controls
- •Server-side Comments
- •Literal Text and HTML Tags
- •View State
- •Working with Directives
- •ASP.NET Languages
- •Visual Basic
- •Summary
- •VB and C# Programming Basics
- •Programming Basics
- •Control Events and Subroutines
- •Page Events
- •Variables and Variable Declaration
- •Arrays
- •Functions
- •Operators
- •Breaking Long Lines of Code
- •Conditional Logic
- •Loops
- •Object Oriented Programming Concepts
- •Objects and Classes
- •Properties
- •Methods
- •Classes
- •Constructors
- •Scope
- •Events
- •Understanding Inheritance
- •Objects In .NET
- •Namespaces
- •Using Code-behind Files
- •Summary
- •Constructing ASP.NET Web Pages
- •Web Forms
- •HTML Server Controls
- •Using the HTML Server Controls
- •Web Server Controls
- •Standard Web Server Controls
- •Label
- •Literal
- •TextBox
- •HiddenField
- •Button
- •ImageButton
- •LinkButton
- •HyperLink
- •CheckBox
- •RadioButton
- •Image
- •ImageMap
- •PlaceHolder
- •Panel
- •List Controls
- •DropDownList
- •ListBox
- •RadioButtonList
- •CheckBoxList
- •BulletedList
- •Advanced Controls
- •Calendar
- •AdRotator
- •TreeView
- •SiteMapPath
- •Menu
- •MultiView
- •Wizard
- •FileUpload
- •Web User Controls
- •Creating a Web User Control
- •Using the Web User Control
- •Master Pages
- •Using Cascading Style Sheets (CSS)
- •Types of Styles and Style Sheets
- •Style Properties
- •The CssClass Property
- •Summary
- •Building Web Applications
- •Introducing the Dorknozzle Project
- •Using Visual Web Developer
- •Meeting the Features
- •The Solution Explorer
- •The Web Forms Designer
- •The Code Editor
- •IntelliSense
- •The Toolbox
- •The Properties Window
- •Executing your Project
- •Using Visual Web Developer’s Built-in Web Server
- •Using IIS
- •Using IIS with Visual Web Developer
- •Core Web Application Features
- •Web.config
- •Global.asax
- •Using Application State
- •Working with User Sessions
- •Using the Cache Object
- •Using Cookies
- •Starting the Dorknozzle Project
- •Preparing the Sitemap
- •Using Themes, Skins, and Styles
- •Creating a New Theme Folder
- •Creating a New Style Sheet
- •Styling Web Server Controls
- •Adding a Skin
- •Applying the Theme
- •Building the Master Page
- •Using the Master Page
- •Extending Dorknozzle
- •Debugging and Error Handling
- •Debugging with Visual Web Developer
- •Other Kinds of Errors
- •Custom Errors
- •Handling Exceptions Locally
- •Summary
- •Using the Validation Controls
- •Enforcing Validation on the Server
- •Using Validation Controls
- •RequiredFieldValidator
- •CompareValidator
- •RangeValidator
- •ValidationSummary
- •RegularExpressionValidator
- •Some Useful Regular Expressions
- •CustomValidator
- •Validation Groups
- •Updating Dorknozzle
- •Summary
- •What is a Database?
- •Creating your First Database
- •Creating a New Database Using Visual Web Developer
- •Creating Database Tables
- •Data Types
- •Column Properties
- •Primary Keys
- •Creating the Employees Table
- •Creating the Remaining Tables
- •Executing SQL Scripts
- •Populating the Data Tables
- •Relational Database Design Concepts
- •Foreign Keys
- •Using Database Diagrams
- •Diagrams and Table Relationships
- •One-to-one Relationships
- •One-to-many Relationships
- •Many-to-many Relationships
- •Summary
- •Speaking SQL
- •Reading Data from a Single Table
- •Using the SELECT Statement
- •Selecting Certain Fields
- •Selecting Unique Data with DISTINCT
- •Row Filtering with WHERE
- •Selecting Ranges of Values with BETWEEN
- •Matching Patterns with LIKE
- •Using the IN Operator
- •Sorting Results Using ORDER BY
- •Limiting the Number of Results with TOP
- •Reading Data from Multiple Tables
- •Subqueries
- •Table Joins
- •Expressions and Operators
- •Transact-SQL Functions
- •Arithmetic Functions
- •String Functions
- •Date and Time Functions
- •Working with Groups of Values
- •The COUNT Function
- •Grouping Records Using GROUP BY
- •Filtering Groups Using HAVING
- •The SUM, AVG, MIN, and MAX Functions
- •Updating Existing Data
- •The INSERT Statement
- •The UPDATE Statement
- •The DELETE Statement
- •Stored Procedures
- •Summary
- •Introducing ADO.NET
- •Importing the SqlClient Namespace
- •Defining the Database Connection
- •Preparing the Command
- •Executing the Command
- •Setting up Database Authentication
- •Reading the Data
- •Using Parameters with Queries
- •Bulletproofing Data Access Code
- •Using the Repeater Control
- •More Data Binding
- •Inserting Records
- •Updating Records
- •Deleting Records
- •Using Stored Procedures
- •Summary
- •DataList Basics
- •Handling DataList Events
- •Editing DataList Items and Using Templates
- •DataList and Visual Web Developer
- •Styling the DataList
- •Summary
- •Using the GridView Control
- •Customizing the GridView Columns
- •Styling the GridView with Templates, Skins, and CSS
- •Selecting Grid Records
- •Using the DetailsView Control
- •Styling the DetailsView
- •GridView and DetailsView Events
- •Entering Edit Mode
- •Using Templates
- •Updating DetailsView Records
- •Summary
- •Advanced Data Access
- •Using Data Source Controls
- •Binding the GridView to a SqlDataSource
- •Binding the DetailsView to a SqlDataSource
- •Displaying Lists in DetailsView
- •More on SqlDataSource
- •Working with Data Sets and Data Tables
- •What is a Data Set Made From?
- •Binding DataSets to Controls
- •Implementing Paging
- •Storing Data Sets in View State
- •Implementing Sorting
- •Filtering Data
- •Updating a Database from a Modified DataSet
- •Summary
- •Security and User Authentication
- •Basic Security Guidelines
- •Securing ASP.NET 2.0 Applications
- •Working with Forms Authentication
- •Authenticating Users
- •Working with Hard-coded User Accounts
- •Configuring Forms Authentication
- •Configuring Forms Authorization
- •Storing Users in Web.config
- •Hashing Passwords
- •Logging Users Out
- •ASP.NET 2.0 Memberships and Roles
- •Creating the Membership Data Structures
- •Using your Database to Store Membership Data
- •Using the ASP.NET Web Site Configuration Tool
- •Creating Users and Roles
- •Changing Password Strength Requirements
- •Securing your Web Application
- •Using the ASP.NET Login Controls
- •Authenticating Users
- •Customizing User Display
- •Summary
- •Working with Files and Email
- •Writing and Reading Text Files
- •Setting Up Security
- •Writing Content to a Text File
- •Reading Content from a Text File
- •Accessing Directories and Directory Information
- •Working with Directory and File Paths
- •Uploading Files
- •Sending Email with ASP.NET
- •Configuring the SMTP Server
- •Sending a Test Email
- •Creating the Company Newsletter Page
- •Summary
- •The WebControl Class
- •Properties
- •Methods
- •Standard Web Controls
- •AdRotator
- •Properties
- •Events
- •BulletedList
- •Properties
- •Events
- •Button
- •Properties
- •Events
- •Calendar
- •Properties
- •Events
- •CheckBox
- •Properties
- •Events
- •CheckBoxList
- •Properties
- •Events
- •DropDownList
- •Properties
- •Events
- •FileUpload
- •Properties
- •Methods
- •HiddenField
- •Properties
- •HyperLink
- •Properties
- •Image
- •Properties
- •ImageButton
- •Properties
- •Events
- •ImageMap
- •Properties
- •Events
- •Label
- •Properties
- •LinkButton
- •Properties
- •Events
- •ListBox
- •Properties
- •Events
- •Literal
- •Properties
- •MultiView
- •Properties
- •Methods
- •Events
- •Panel
- •Properties
- •PlaceHolder
- •Properties
- •RadioButton
- •Properties
- •Events
- •RadioButtonList
- •Properties
- •Events
- •TextBox
- •Properties
- •Events
- •Properties
- •Validation Controls
- •CompareValidator
- •Properties
- •Methods
- •CustomValidator
- •Methods
- •Events
- •RangeValidator
- •Properties
- •Methods
- •RegularExpressionValidator
- •Properties
- •Methods
- •RequiredFieldValidator
- •Properties
- •Methods
- •ValidationSummary
- •Properties
- •Navigation Web Controls
- •SiteMapPath
- •Properties
- •Methods
- •Events
- •Menu
- •Properties
- •Methods
- •Events
- •TreeView
- •Properties
- •Methods
- •Events
- •HTML Server Controls
- •HtmlAnchor Control
- •Properties
- •Events
- •HtmlButton Control
- •Properties
- •Events
- •HtmlForm Control
- •Properties
- •HtmlGeneric Control
- •Properties
- •HtmlImage Control
- •Properties
- •HtmlInputButton Control
- •Properties
- •Events
- •HtmlInputCheckBox Control
- •Properties
- •Events
- •HtmlInputFile Control
- •Properties
- •HtmlInputHidden Control
- •Properties
- •HtmlInputImage Control
- •Properties
- •Events
- •HtmlInputRadioButton Control
- •Properties
- •Events
- •HtmlInputText Control
- •Properties
- •Events
- •HtmlSelect Control
- •Properties
- •Events
- •HtmlTable Control
- •Properties
- •HtmlTableCell Control
- •Properties
- •HtmlTableRow Control
- •Properties
- •HtmlTextArea Control
- •Properties
- •Events
- •Index
Chapter 6: Using the Validation Controls
</body>
</html>
When this form is submitted, the CustomValidator control raises the ServerValidate event, and the CheckUniqueUserName method is called as a result. At the moment, our list of usernames is limited to zak and cristian. If the new username matches either of these, e.IsValid is set to False, and the error message is displayed; otherwise, we assume that the username is valid. When our submitButton_Click event handler checks the Page.IsValid property, e.IsValid returns False if the user entered zak or cristian, and True if the new username is anything else.
Although this example shows a very simple CustomValidator, you can certainly imagine the possibilities this class makes available. For example, while we won’t explore it in this book, you could create a client-side validation function for your
CustomValidator controls by means of the ClientValidationFunction property. For details, refer to the .NET Framework SDK Documentation for the
CustomValidator control.
Validation Groups
A very useful new feature in ASP.NET 2.0, validation groups allow us to validate individual parts of a web page independently of its other sections. This capability proves particularly handy when you’re working with complex pages that contain many functional components. For example, consider the scenario of a single page that contains a login form and a quick registration form, each with its own Submit button and its own set of validation controls. Certainly we don’t want the functionality of the login form’s Submit button to be affected by the data in the registration form; nor can we allow the login form’s data to affect submission of the registration form.
The solution to this problem is to set the controls in each of the boxes within different validation groups. You can assign a control to a validation group using its ValidationGroup property, as shown in the following code:
File: ValidationGroups.aspx (excerpt)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Validation Groups Demo</title> </head>
242
Validation Groups
<body>
<form id="Form1" runat="server"> <!-- Login Controls --> <h1>Login</h1>
<!-- Username --> <p>
Username:<br />
<asp:TextBox id="usernameTextBox" runat="server" /> <asp:RequiredFieldValidator id="usernameReq"
runat="server" ControlToValidate="usernameTextBox" ErrorMessage="Username is required!" SetFocusOnError="True" ValidationGroup="Login" />
</p>
<!-- Password --> <p>
Password:<br />
<asp:TextBox id="passwordTextBox" runat="server" TextMode="Password" />
<asp:RequiredFieldValidator id="passwordReq" runat="server" ControlToValidate="passwordTextBox" ErrorMessage="Password is required!" SetFocusOnError="True" ValidationGroup="Login" />
</p>
<p>
<asp:Button ID="loginButton" runat="server" Text="Log In"
ValidationGroup="Login" />
</p>
<!-- Login Controls --> <h1>Register</h1>
<!-- Username --> <p>
Username:<br />
<asp:TextBox id="newUserNameTextBox" runat="server" /> <asp:RequiredFieldValidator id="newUserNameReq"
runat="server" ControlToValidate="newUserNameTextBox" ErrorMessage="Username is required!" SetFocusOnError="True" ValidationGroup="Register" />
</p>
<!-- Password --> <p>
Password:<br />
<asp:TextBox id="newPasswordTextBox" runat="server" TextMode="Password" />
<asp:RequiredFieldValidator id="newPasswordReq" runat="server" ControlToValidate="newPasswordTextBox" ErrorMessage="Password is required!"
243
Chapter 6: Using the Validation Controls
SetFocusOnError="True" ValidationGroup="Register" />
</p>
<p>
<asp:Button ID="registerButton" runat="server" Text="Register" ValidationGroup="Register" />
</p>
</form>
</body>
</html>
Executing this page reveals the two sets of controls: one for logging in an existing user, and another for registering a new user. To keep things simple, the only validation we’ve implemented in this example is achieved through
RequiredFieldValidator controls.
Clicking the Log In button triggers only those validators that share that button’s ValidationGroup setting, as Figure 6.10 indicates.
Figure 6.10. Triggering the Login ValidationGroup
Likewise, clicking the Register button triggers the second set of validators, and deactivates the first, as Figure 6.11 shows.
244
Updating Dorknozzle
Default Validation Groups
Controls that aren’t specifically assigned to any validation group are aggregated into a default validation group. In other words, a button that isn’t assigned to any validation group will trigger only those validation controls that aren’t assigned to any groups.
Finally, remember that Page.IsValid returns the results of the current validation group (i.e. the one that caused the server-side event). To verify the validity of another group on the page, we use the Page.Validate method, which can receive as parameter the name of the validation group to be validated.
Figure 6.11. Activating the RegisterValidationGroup
Updating Dorknozzle
Now that you’ve spent some time with validation controls, let’s use them to update Dorknozzle’s Help Desk page. The following rules must be met before the user can submit a new help desk request:
The station number text box cannot be empty.
The station number must be a valid number.
245
Chapter 6: Using the Validation Controls
The station number must be a numeral between 1 and 50.
A description of the problem must be entered.
To make changes to the help desk page, you first need to load the Dorknozzle project in Visual Web Developer. Go to File > Open Web Site… and select the Dorknozzle project.
Loading Multiple Projects
Did you know that you can work with multiple projects at the same time? You can launch multiple instances of Visual Web Developer and load a different web application in each of them.
After Dorknozzle loads, open HelpDesk.aspx in the editor and make the following changes to the file:
File: HelpDesk.aspx (excerpt)
<%@ Page Language="VB" MasterPageFile="~/Dorknozzle.master" AutoEventWireup="false" CodeFile="HelpDesk.aspx.vb" Inherits="HelpDesk" title="Dorknozzle Help Desk" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<h1>Employee Help Desk Request</h1> <p>
Station Number:<br />
<asp:TextBox id="stationTextBox" runat="server" CssClass="textbox" />
<asp:RequiredFieldValidator id="stationNumReq" runat="server" ControlToValidate="stationTextBox"
ErrorMessage="<br />You must enter a station number!" Display="Dynamic" />
<asp:CompareValidator id="stationNumCheck" runat="server" ControlToValidate="stationTextBox" Operator="DataTypeCheck" Type="Integer" ErrorMessage="<br />The value must be a number!" Display="Dynamic" />
<asp:RangeValidator id="stationNumRangeCheck" runat="server" ControlToValidate="stationTextBox"
MinimumValue="1" MaximumValue="50" Type="Integer" ErrorMessage="<br />Number must be between 1 and 50." Display="Dynamic" />
</p>
<p>
Problem Category:<br />
246
Updating Dorknozzle
<asp:DropDownList id="categoryList" runat="server" CssClass="dropdownmenu" />
</p>
<p>
Problem Subject:<br />
<asp:DropDownList id="subjectList" runat="server" CssClass="dropdownmenu" />
</p>
<p>
Problem Description:<br />
<asp:TextBox id="descriptionTextBox" runat="server" CssClass="textbox" Columns="40" Rows="4" TextMode="MultiLine" />
<asp:RequiredFieldValidator id="descriptionReq" runat="server" ControlToValidate="descriptionTextBox"
ErrorMessage="<br />You must enter a description!" Display="Dynamic" />
</p>
<p>
<asp:Button id="submitButton" runat="server" CssClass="button" Text="Submit Request" />
</p>
</asp:Content>
Now execute the project, and select the Help Desk page from the menu. Clicking
Submit without entering valid data triggers the validation controls, as Figure 6.12 shows.
247
Chapter 6: Using the Validation Controls
Figure 6.12. Validation controls in action on the Dorknozzle Help Desk
Right now, we’re not doing anything with the data that’s been entered, but we’ll take care of that in following chapters. When we finally do something with this data, we don’t want our server-side code to try to work with invalid data. Let’s add the safety check to the server side as well, to make sure we have a solid foundation from which to start developing our server-side functionality in the next chapters.
Stop the project from within Visual Web Developer, and open HelpDesk.aspx in Design View. There, double-click the Submit Request button to have its Click event handler generated for you.
248
Updating Dorknozzle
Complete the automatically generated code as shown below:
Visual Basic File: HelpDesk.aspx.vb (excerpt)
Protected Sub submitButton_Click(ByVal sender As Object, _
|
ByVal e As System.EventArgs) Handles submitButton.Click |
|
If Page.IsValid Then |
|
' Code that uses the data entered by the user |
|
End If |
End Sub |
|
C# |
File: HelpDesk.aspx.cs (excerpt) |
protected void submitButton_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
// Code that uses the data entered by the user
}
}
Up to this point, we’ve only discussed one way of tying a control’s event to an event handler method. This approach involves setting a property, such as OnClick, on the control, as shown here:
C# File: HelpDesk.aspx (excerpt)
<asp:Button id="submitButton" runat="server" CssClass="button" Text="Submit Request" OnClick="submitButton_Click" />
This property causes ASP.NET to call a method named submitButton_Click whenever this button is clicked. If you’re using C#, you’ll see that Visual Web
Developer added this property to submitButton when it generated your event handler, as is shown above.
However, if you’re using VB, this property is not added. Instead, Visual Web Developer uses the VB-specific keyword Handles, followed by the name of the control that’s responsible for raising the event, and finally the name of the event that’s being handled (in our case, submitButton.Click). This generated code is shown below:
Visual Basic |
File: HelpDesk.aspx.vb (excerpt) |
|
|
Protected |
Sub submitButton_Click(ByVal sender As Object, _ |
ByVal |
e As System.EventArgs) Handles submitButton.Click |
|
|
This is simply an alternative way of tying this method to the submitButton control’s Click event.
249