- •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 12: Advanced Data Access
It’s easy to imagine how quickly you could fill a page containing many GridViews using only one DataSet as the source.
As you’ve learned thus far, DataTables are elements that hold data within a DataSet. Just like tables in a database, DataTables are built from columns and rows. However, unlike tables in databases, DataTables reside in memory, which gives us the ability to page, sort, and filter the data in ways that just wouldn’t be possible with an SqlDataReader.
Implementing Paging
We saw the GridView’s paging functionality in action earlier in this chapter. When we bound the GridView to the SqlDataProvider, the paging functionality was automatically implemented. Now that we’re binding the GridView to a DataSet, there’s a little more work involved in getting paging up and running. However, the effort will be more than worthwhile if performance is an issue in your application.
The task of implementing paging in a GridView that has been bound to an SqlDataAdapter is a two-step process. First, we need to set the AllowPaging property of the GridView to True, and set its PageSize value to reflect the number of items we want to see on every page. Open Departments.aspx in Visual Web Developer and set AllowPaging to True, and PageSize to 4 on the departmentsGrid control, as shown below:
File: Departments.aspx (excerpt)
<asp:GridView id="departmentsGrid" runat="server"
AllowPaging="True" PageSize="4"> </asp:GridView>
Next, we need to handle the PageIndexChanging event of the GridView control. This event is fired when the user clicks one of the paging controls; we’ll need to update the data displayed in the grid accordingly.
Double-click the PageIndexChanging entry in the Properties window, as shown in Figure 12.24, to have Visual Web Developer generate an empty PageIndexChanging event handler for you.
504
Implementing Paging
Figure 12.24. Creating the PageIndexChanging event handler
Finally, fill in the generated event handler as shown below:
Visual Basic |
File: Departments.aspx.vb (excerpt) |
|
|
Protected |
Sub departmentsGrid_PageIndexChanging( _ |
ByVal |
sender As Object, _ |
ByVal |
e As System.Web.UI.WebControls.GridViewPageEventArgs) _ |
Handles departmentsGrid.PageIndexChanging ' Retrieve the new page index
Dim newPageIndex As Integer = e.NewPageIndex
'Set the new page index of the GridView departmentsGrid.PageIndex = newPageIndex
'Bind the grid to its data source again to update its contents BindGrid()
End Sub
C# |
File: Departments.aspx.cs (excerpt) |
protected void departmentsGrid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
// Retrieve the new page index
int newPageIndex = e.NewPageIndex;
//Set the new page index of the GridView departmentsGrid.PageIndex = newPageIndex;
//Bind the grid to its data source again to update its
//contents
BindGrid();
}
In this code, we’ve retrieved the index of the requested page from e.NewPageIndex parameter, and used its value to set the PageIndex property of the GridView. We’ve then bound the grid to its data source once more.
505
Chapter 12: Advanced Data Access
Execute the project again. When you click a paging link within the grid, the display should update quickly, as Figure 12.25 shows.
Figure 12.25. Viewing Departments with paging functionality
Storing Data Sets in View State
Now, we’re able to page through our list of departments, but the code isn’t anywhere near as efficient as it could be. Every time we display another page of departments in our GridView, we call the BindData method, which executes the following code in order to retrieve a list of departments:
Visual Basic File: Departments.aspx.vb (excerpt)
' Initialize connection
conn = New SqlConnection(connectionString) ' Create adapter
adapter = New SqlDataAdapter( _
"SELECT DepartmentID, Department FROM Departments", conn) ' Fill the DataSet
adapter.Fill(dataSet, "Departments")
506
Storing Data Sets in View State
C# File: Departments.aspx.cs (excerpt)
// Initialize connection
conn = new SqlConnection(connectionString); // Create adapter
adapter = new SqlDataAdapter(
"SELECT DepartmentID, Department FROM Departments", conn); // Fill the DataSet
adapter.Fill(dataSet, "Departments");
Given that this list of departments is unlikely to change a great deal, wouldn’t it be better if we had to query the database only once? Well, given that we now have a complete copy of the data in the Departments table, we can! Modify the BindGrid method as shown below:
Visual Basic File: Departments.aspx.vb (excerpt)
Private Sub BindGrid() ' Define data objects
Dim conn As SqlConnection Dim dataSet As New DataSet
Dim adapter As SqlDataAdapter
If ViewState("DepartmentsDataSet") Is Nothing Then
'Read the connection string from Web.config Dim connectionString As String = _
ConfigurationManager.ConnectionStrings( _ "Dorknozzle").ConnectionString
'Initialize connection
conn = New SqlConnection(connectionString) ' Create adapter
adapter = New SqlDataAdapter( _
"SELECT DepartmentID, Department FROM Departments", _ conn)
'Fill the DataSet adapter.Fill(dataSet, "Departments")
'Store the DataSet in view state ViewState("DepartmentsDataSet") = dataSet
Else
dataSet = ViewState("DepartmentsDataSet") End If
' Bind the grid to the DataSet departmentsGrid.DataSource = dataSet departmentsGrid.DataBind()
End Sub
507
Chapter 12: Advanced Data Access
C# File: Departments.aspx.cs (excerpt)
private void BindGrid()
{
// Define data objects SqlConnection conn;
DataSet dataSet = new DataSet(); SqlDataAdapter adapter; if(ViewState["DepartmentsDataSet"] == null)
{
//Read the connection string from Web.config string connectionString =
ConfigurationManager.ConnectionStrings[
"Dorknozzle"].ConnectionString;
//Initialize connection
conn = new SqlConnection(connectionString); // Create adapter
adapter = new SqlDataAdapter(
"SELECT DepartmentID, Department FROM Departments", conn);
//Fill the DataSet adapter.Fill(dataSet, "Departments");
//Store the DataSet in view state ViewState["DepartmentsDataSet"] = dataSet;
}
else
{
dataSet = (DataSet)ViewState["DepartmentsDataSet"];
}
// Bind the grid to the DataSet departmentsGrid.DataSource = dataSet; departmentsGrid.DataBind();
}
Here, we’re using the ViewState collection to store our DataSet. The ViewState collection works a lot like the Session collection, except that instead of storing data for access by the entire application, ViewState stores data for just this one page while the user is interacting with it. If the users navigate away from this page, the data in ViewState will be lost—even if they return to the page within the same session.
In this revised version of BindGrid, we start by checking the ViewState collection for an item named DepartmentsDataSet. If no such item exists, we create a new DataSet, fill it with data from the database, as before, and store it in ViewState. If an item named DepartmentsDataSet does exist in ViewState, we simply save
508