- •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
Bulletproofing Data Access Code
Figure 9.7. An invalid ID warning
Bulletproofing Data Access Code
Right now, the code in QueryParameters.aspx seems to be perfect, right? Well, not quite. While the code does its job most of the time, it still has one important weakness: it doesn’t take into account potential errors that could occur in the data access code. It’s very good practice to enclose such code in Try-Catch-Finally blocks, and always to use the Finally block to close any open data objects. We learned about Try-Catch-Finally in Chapter 5; now we’re going to use that theory in a real-world scenario.
Take a look at the following code samples.
Visual Basic File: QueryParameters.aspx (excerpt)
Protected Sub submitButton_Click(ByVal sender As Object, _ ByVal e As System.EventArgs)
' Define data objects
Dim conn As SqlConnection Dim comm As SqlCommand
Dim reader As SqlDataReader ' Initialize connection
conn = New SqlConnection("Server=localhost\SqlExpress;" & _ "Database=Dorknozzle;Integrated Security=True")
' Create command
comm = New SqlCommand( _
"SELECT EmployeeID, Name, Username, Password " & _ "FROM Employees WHERE EmployeeID=@EmployeeID", conn)
' Verify if the ID entered by the visitor is numeric Dim employeeID As Integer
If (Not Integer.TryParse(idTextBox.Text, employeeID)) Then ' If the user didn't enter numeric ID...
351
Chapter 9: ADO.NET
userLabel.Text = "Please enter a numeric ID!" Else
' Add parameter
comm.Parameters.Add("@EmployeeID", System.Data.SqlDbType.Int) comm.Parameters("@EmployeeID").Value = employeeID
' Enclose database code in Try-Catch-Finally Try
'Open the connection conn.Open()
'Execute the command
reader = comm.ExecuteReader() ' Display the requested data If reader.Read() Then
userLabel.Text = "Employee ID: " & _ reader.Item("EmployeeID") & "<br />" & _ "Name: " & reader.Item("Name") & "<br />" & _
"Username: " & reader.Item("Username") & "<br />" & _ "Password: " & reader.Item("Password")
Else
userLabel.Text = _
"There is no user with this ID: " & employeeID
End If reader.Close()
Catch
' Display error message
userLabel.Text = "Error retrieving user data." Finally
' Close the connection |
|
conn.Close() |
|
End Try |
|
End If |
|
End Sub |
|
C# |
File: QueryParameters.aspx (excerpt) |
protected void submitButton_Click(object sender, EventArgs e)
{
//Declare objects SqlConnection conn; SqlCommand comm; SqlDataReader reader;
//Initialize connection
conn = new SqlConnection("Server=localhost\\SqlExpress;" + "Database=Dorknozzle;Integrated Security=True");
// Create command
comm = new SqlCommand(
"SELECT EmployeeID, Name, Username, Password " +
352
Bulletproofing Data Access Code
"FROM Employees WHERE EmployeeID=@EmployeeID", conn); // Verify if the ID entered by the visitor is numeric
int employeeID;
if (!int.TryParse(idTextBox.Text, out employeeID))
{
// If the user didn't enter numeric ID...
userLabel.Text = "Please enter a numeric ID!";
}
else
{
// Add parameter
comm.Parameters.Add("@EmployeeID", System.Data.SqlDbType.Int); comm.Parameters["@EmployeeID"].Value = employeeID;
// Enclose database code in Try-Catch-Finally try
{
//Open the connection conn.Open();
//Execute the command
reader = comm.ExecuteReader();
//Display the requested data if (reader.Read())
{
userLabel.Text = "Employee ID: " + reader["EmployeeID"] + "<br />" + "Name: " + reader["Name"] + "<br />" +
"Username: " + reader["Username"] + "<br />" + "Password: " + reader["Password"];
}
else
{
userLabel.Text =
"There is no user with this ID: " + employeeID;
}
//Close the reader and the connection reader.Close();
}
catch
{
// Display error message
userLabel.Text = "Error retrieving user data.";
}
finally
{
// Close the connection conn.Close();
353
Chapter 9: ADO.NET
}
}
}
So, what’s new in this version of the event handler, apart from the fact that it’s become larger? First of all—and most important—we have the Try-Catch-Finally block in place. Everything that manipulates the database is in the Try block. If an error arises, we display a message for the user through the Catch block. In the Finally block, which is always guaranteed to execute, we close the database connection.
Using the Repeater Control
The .NET Framework comes bundled with a few controls that can help us to display more complex lists of data: Repeater, DataList, GridView, DetailsView, and FormView. These controls allow you to easily format database data within an ASP.NET page.
In this chapter, you’ll learn how to work with the Repeater; we’ll cover the other controls in the next few chapters. Note that these controls aren’t part of ADO.NET, but we’re presenting them together with ADO.NET because they’re frequently used in work with databases.
Where’s the DataGrid?
ASP.NET 1.0 and ASP.NET 1.1 developers may wonder what happened to the DataGrid control, which used to be the control of choice for displaying grids of data. Though that control still exists in ASP.NET 2.0, the more powerful and flexible GridView is now the control of choice. Unless you need to maintain older applications, the GridView control should be used. The difference between DataGrid and GridView is covered very nicely in the article GridView: Move Over DataGrid, There’s a New Grid in Town!1
The Repeater control is a lightweight ASP.NET control that allows the easy presentation of data directly from a data source, usually in just a handful of lines of code. Let’s look at a quick example of how a Repeater control can be added to a page:
<asp:Repeater id="myRepeater" runat="server"> <ItemTemplate>
<%# Eval("Name") %>
1 http://msdn.microsoft.com/msdnmag/issues/04/08/GridView/
354
Using the Repeater Control
</ItemTemplate>
</asp:Repeater>
As you can see, the Repeater control looks a little different to the other web controls we’ve used thus far. The difference with this control is that it has an <ItemTemplate> subtag—otherwise known as a child tag—located within the main <asp:Repeater> tag, or parent tag. This child tag contains a code render block that specifies the particular data item that we want to appear in the Repeater. However, before this data can be displayed, we have to bind an SqlDataReader object (which contains the results of an SQL query) to the Repeater control using the process known as data binding. This task is achieved from a code block like so:
myRepeater.DataSource = reader myRepeater.DataBind()
It’s that easy! In a moment, we’ll display the code within the framework of a new example. First, let’s discuss what’s happening here in more detail.
True to its name, the Repeater control lets us output some markup for each record in an SqlDataReader, inserting values from those records wherever we like in this repeated markup. The markup to be repeated is provided as templates for the Repeater to use. For example, if we wanted to display the results of a database query in an HTML table, we could use a Repeater to generate an HTML table row for each record in that results set. We’d provide a template containing <tr> and </tr> tags, as well as <td> and </td> tags, and we’d indicate where in that template we wanted the values from the results set to appear.
To gain greater flexibility in the presentation of our results, we can provide the
Repeater control with a number of different types of templates, which the Repeater will use in the circumstances described in the list of templates below. Each of these templates must be specified in a child tag of the <asp:Repeater> tag:
<HeaderTemplate>
This template provides a header for the output. If we’re generating an HTML table, for example, we could include the opening <table> tag, provide a row of header cells (th), and even specify a caption for the table.
<ItemTemplate>
The only template that is actually required, <ItemTemplate> specifies the markup that should be output for each item in the data source. If we were
355
Chapter 9: ADO.NET
generating an HTML table, this template would contain the <td> and </td> tags and their contents.
<AlternatingItemTemplate>
This template, if provided, will be applied instead of ItemTemplate to every second record in the data source, making it easy to produce effects such as alternating table row colors.
<SeparatorTemplate>
This template provides markup that will appear between the items in the data source. It will not appear before the first item or after the last item.
<FooterTemplate>
This template provides a footer for the resulting output, which will appear after all the items in the data source. If you’re generating an HTML table, you could include the closing </table> tag in this template.
Let’s take a look at a repeater control that displays a table of employees. If you want to test this code, create a new web form named UsingRepeater.aspx in the Learning application. Don’t use a code-behind file or a master page. Import the System.Data.SqlClient namespace just as you did for the other two forms we’ve created in this chapter.
The following code will set up a Repeater that can be used to display a table of employees, listing their employee IDs, names, usernames, and passwords:
File: UsingRepeater.aspx (excerpt)
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server"> </script>
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">
<title>Using the Repeater</title> </head>
<body>
<form id="form1" runat="server"> <div>
<asp:Repeater ID="myRepeater" runat="server">
356
Using the Repeater Control
<HeaderTemplate>
<table width="400" border="1"> <tr>
<th>Employee ID</th> <th>Name</th> <th>Username</th> <th>Password</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("EmployeeID") %></td> <td><%# Eval("Name") %></td> <td><%# Eval("Username") %></td> <td><%# Eval("Password") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>
The Repeater control naturally lends itself to generating HTML tables, and that’s just what we’re doing here. First, we include a <HeaderTemplate>, which includes the opening <table> tag, along with the table’s heading row.
Next, we provide a template for each item in the result set. The template specifies a table row containing four table cells, each of which contains a code render block that outputs the values taken from each record in the results set. In both VB and C#, we use Eval to retrieve database values. Alternatively, you could use the longer form, Container.DataItem("FieldName") in VB.NET or DataBinder.Eval(Container.DataItem, "FieldName") in C#, but we’ll stick with Eval in this book.
Finally, here’s the <FooterTemplate> that includes the closing </table> tag.
To make the repeater display any information, we need to bind a data source to it. Use Visual Web Developer to generate the web form’s Load event handler, and complete it like this:
357
Chapter 9: ADO.NET
Visual Basic File: UsingRepeater.aspx (excerpt)
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs)
' Define data objects
Dim conn As SqlConnection Dim comm As SqlCommand
Dim reader As SqlDataReader ' Initialize connection
conn = New SqlConnection("Server=localhost\SqlExpress;" & _ "Database=Dorknozzle;Integrated Security=True")
' Create command
comm = New SqlCommand( _
"SELECT EmployeeID, Name, Username, Password " & _ "FROM Employees", conn)
' Enclose database code in Try-Catch-Finally Try
'Open the connection conn.Open()
'Execute the command
reader = comm.ExecuteReader()
'Bind the repeater to the data source myRepeater.DataSource = reader myRepeater.DataBind()
'Close the data reader
reader.Close() Catch
' |
Display error message |
Response.Write("Error retrieving user data.") |
|
Finally |
|
' |
Close the connection |
conn.Close() |
|
End |
Try |
End Sub |
|
|
|
C# |
File: UsingRepeater.aspx (excerpt) |
protected void Page_Load(object sender, EventArgs e)
{
//Declare objects SqlConnection conn; SqlCommand comm; SqlDataReader reader;
//Initialize connection
conn = new SqlConnection("Server=localhost\\SqlExpress;" + "Database=Dorknozzle;Integrated Security=True");
// Create command
comm = new SqlCommand(
358
Using the Repeater Control
"SELECT EmployeeID, Name, Username, Password " + "FROM Employees", conn);
// Enclose database code in Try-Catch-Finally try
{
//Open the connection conn.Open();
//Execute the command
reader = comm.ExecuteReader();
//Bind the repeater to the data source myRepeater.DataSource = reader; myRepeater.DataBind();
//Close the data reader reader.Close();
}
catch
{
// Display error message
Response.Write("Error retrieving user data.");
}
finally
{
// Close the connection conn.Close();
}
}
Figure 9.8. Using the Repeater control
359
Chapter 9: ADO.NET
As you can see, by binding a control to a data source, it’s very easy to get our data to display in the web form. In this case, we’ve used the Repeater control, which, in the server-side code, we bound to the SqlDataReader that contains our data. The results of this work are shown in Figure 9.8.
Creating the Dorknozzle Employee
Directory
Great work! You’re presenting data in the browser window based on user interaction, and you’ve even allowed your users to filter that data in accordance with their own search parameters. Your code also takes care to always close the database connection in case an error occurs along the way.
It’s time to apply the theory we’re learning directly to the Dorknozzle application. In the following pages, you'll insert, update, and delete database records in a new Dorknozzle Employee Directory web form. You’ll also learn how to call stored procedures using ADO.NET.
Start by loading the Dorknozzle project and creating a new web form. Make sure you name it EmployeeDirectory.aspx, check that both the Place code in separate file and the Select master page checkboxes are checked, and confirm that your new page is based on the master page Dorknozzle.master. Then, modify the automatically generated code like this:
File: EmployeeDirectory.aspx (excerpt)
<%@ Page Language="VB" MasterPageFile="~/Dorknozzle.master" AutoEventWireup="true" CodeFile="EmployeeDirectory.aspx.vb" Inherits="EmployeeDirectory"
title="Dorknozzle Employee Directory" %> <asp:Content ID="Content1"
ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<h1>Employee Directory</h1>
<asp:Repeater id="employeesRepeater" runat="server"> <ItemTemplate>
Employee ID: <strong><%#Eval("EmployeeID")%></strong><br /> Name: <strong><%#Eval("Name")%></strong><br /> Username: <strong><%#Eval("Username")%></strong>
</ItemTemplate>
<SeparatorTemplate> <hr />
</SeparatorTemplate>
360
Creating the Dorknozzle Employee Directory
</asp:Repeater>
</asp:Content>
This Repeater includes item and separator templates. The item template contains code render blocks that will display the data from an SqlDataReader. When this repeater is properly populated with data, the employee directory page will look like the one shown in Figure 9.9.
Figure 9.9. The completed Employee Directory page
We’ll write the code that populates the repeater in the Page_Load method within our code-behind file. To have the method’s signature generated for you, switch the form to Design View, and double-click an empty space on the form (not in the space of other controls such as the Repeater; a good place to double-click would be to the right of the Employee Directory header). Then, add this code:
Visual Basic |
File: EmployeeDirectory.aspx.vb (excerpt) |
Imports System.Data.SqlClient
Imports System.Configuration
Partial Class EmployeeDirectory
Inherits System.Web.UI.Page
361
Chapter 9: ADO.NET
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load
' Define data objects
Dim conn As SqlConnection Dim comm As SqlCommand
Dim reader As SqlDataReader
'Read the connection string from Web.config Dim connectionString As String = _
ConfigurationManager.ConnectionStrings( _ "Dorknozzle").ConnectionString
'Initialize connection
conn = New SqlConnection(connectionString) ' Create command
comm = New SqlCommand( _
"SELECT EmployeeID, Name, Username FROM Employees", _ conn)
' Enclose database code in Try-Catch-Finally Try
'Open the connection conn.Open()
'Execute the command
reader = comm.ExecuteReader()
'Bind the reader to the repeater employeesRepeater.DataSource = reader employeesRepeater.DataBind()
'Close the reader
reader.Close() Finally
' Close the connection conn.Close()
End Try
End Sub End Class
C# File: EmployeeDirectory.aspx.cs (excerpt)
using System; using System.Data;
using System.Configuration; using System.Collections; using System.Web;
using System.Web.Security; using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
362
Creating the Dorknozzle Employee Directory
public partial class EmployeeDirectory : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Define data objects SqlConnection conn; SqlCommand comm; SqlDataReader reader;
//Read the connection string from Web.config string connectionString =
ConfigurationManager.ConnectionStrings[
"Dorknozzle"].ConnectionString;
//Initialize connection
conn = new SqlConnection(connectionString); // Create command
comm = new SqlCommand(
"SELECT EmployeeID, Name, Username FROM Employees", conn);
// Enclose database code in Try-Catch-Finally try
{
//Open the connection conn.Open();
//Execute the command
reader = comm.ExecuteReader();
//Bind the reader to the repeater employeesRepeater.DataSource = reader; employeesRepeater.DataBind();
//Close the reader
reader.Close();
}
finally
{
// Close the connection conn.Close();
}
}
}
Most of the code should look familiar, except for the following bit, which reads the connection string:
Visual Basic |
File: EmployeeDirectory.aspx.vb (excerpt) |
' Read the connection string from Web.config Dim connectionString As String =
363
Chapter 9: ADO.NET
|
ConfigurationManager.ConnectionStrings( |
|
"Dorknozzle").ConnectionString |
C# |
File: EmployeeDirectory.aspx.cs (excerpt) |
// Read the connection string from Web.config
string connectionString = ConfigurationManager.ConnectionStrings[ "Dorknozzle"].ConnectionString;
Back in Chapter 5, you learned that you can store various configuration options in Web.config. Anticipating that many applications will use Web.config to store their connection strings, the designers of .NET reserved a special place in Web.config for database connection strings. If you open Web.config now, you’ll see an empty connectionStrings element located inside the configuration element. Modify Web.config like this:
File: Web.config (excerpt)
<configuration>
<connectionStrings>
<add name="Dorknozzle" connectionString="Server=localhost\SqlExpress;
Database=Dorknozzle;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>
You can add more connection strings under the connectionStrings element by inserting add elements with three attributes: connectionString contains the actual connection string, name gives the connection string an identifier that we can reference within our code, and providerName indicates the type of data provider we want to use for the connection. In our case, providerName="System.Data.SqlClient" specifies that we’re connecting to an SQL Server database.
To retrieve configuration data from Web.config we use the
ConfigurationManager class, which is located in the System.Configuration namespace.
Also, you may have noticed that we don’t have a Catch block in our database handling code. When a Catch block is not present, any exceptions that are raised are not caught, although the code in the Finally block is still executed. In other words, we’re choosing not to handle potential errors in EmployeeDirectory.aspx, but we still want to ensure that the database connection is properly closed if an error arises.
364