After opening the page in Listing 9.2, if you enter a connection string that looks like this: Server=localhost;UID=webuser;pwd=secret;database=Northwind the page converts the connection
Trang 1<body>
<form id=”form1” runat=”server”>
<div>
<asp:TextBox
id=”txtConnectionString”
Columns=”60”
Runat=”Server” />
<asp:Button
id=”btnConvert”
Text=”Convert”
OnClick=”btnConvert_Click”
Runat=”Server” />
<hr />
<asp:Label
id=”lblResult”
Runat=”server” />
</div>
</form>
</body>
</html>
After opening the page in Listing 9.2, if you enter a connection string that looks like this:
Server=localhost;UID=webuser;pwd=secret;database=Northwind
the page converts the connection string to look like this:
Data Source=localhost;Initial Catalog=Northwind;User ID=webuser;Password=secret
Connecting to Other Databases
If you need to connect to any database server other than Microsoft SQL Server, you need
to modify the SqlDataSource control’s ProviderName property
The NET Framework includes the following providers:
System.Data.OracleClient—Use the ADO.NET provider for Oracle when connecting
to an Oracle database
System.Data.OleDb—Use the OLE DB provider when connecting to a data source
that supports an OLE DB provider
System.Data.Odbc—Use the ODBC provider when connecting to a data source with
an ODBC driver
Trang 2NOTE
You can configure additional providers that you can use with the SqlDataSource
control by adding new entries to the <DbProviderFactories> section of the
Machine.config file
For performance reasons, you should always use the native ADO.NET provider for a
data-base However, if your database does not have an ADO.NET provider, you need to use
either OLE DB or ODBC to connect to the database Almost every database under the sun
has either an OLE DB provider or an ODBC driver
For example, the page in Listing 9.3 uses the ADO.NET Oracle provider to connect to an
Oracle database
LISTING 9.3 ConnectOracle.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Connect Oracle</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdOrders”
DataSourceID=”srcOrders”
Runat=”server” />
<asp:SqlDataSource
id=”srcOrders”
ProviderName=”System.Data.OracleClient”
SelectCommand=”SELECT * FROM Orders”
ConnectionString=”Data Source=OracleDB;Integrated Security=yes”
Runat=”server” />
</div>
</form>
</body>
</html>
Trang 3In Listing 9.3, the ProviderName property is set to the value System.Data.OracleClient
The connection uses the native ADO.NET Oracle provider instead of the default provider
for Microsoft SQL Server
NOTE
To connect to an Oracle database, you need to install the Oracle client software on
your web server
NOTE
Oracle has produced its own native ADO.NET provider You can download the Oracle
provider at http://www.oracle.com/technology/tech/windows/odpnet/index.html
Storing Connection Strings in the Web Configuration File
Storing connection strings in your pages is a bad idea for three reasons First, it is not a
good practice from the perspective of security In theory, no one should ever view the
source code of your ASP.NET pages In practice, however, hackers have discovered security
flaws in ASP.NET Framework To sleep better at night, you should store your connection
strings in a separate file
Also, adding a connection string to every page makes it difficult to manage a website If
you ever need to change your password, you need to change every page that contains it
If, on the other hand, you store the connection string in one file, you can update the
password by modifying the single file
Finally, storing a connection string in a page can, potentially, hurt the performance of
your application The ADO.NET provider for SQL Server automatically uses connection
pooling to improve your application’s data access performance Instead of being destroyed
when they are closed, the connections are kept alive so that they can be put back into
service quickly when the need arises However, only connections created with the same
connection strings are pooled together (An exact character-by-character match is made.)
Adding the same connection string to multiple pages is a recipe for defeating the benefits
of connection pooling
For these reasons, you should always place your connection strings in the web
configura-tion file The Web.Config file in Listing 9.4 includes a connectionStrings section
LISTING 9.4 Web.Config
<?xml version=”1.0”?>
<configuration>
<connectionStrings>
<add name=”Movies” connectionString=”Data Source=.\SQLEXPRESS;
AttachDbFilename=|DataDirectory|MyDatabase.mdf;Integrated Security=True;
User Instance=True” />
Trang 4</connectionStrings>
</configuration>
You can add as many connection strings to the connectionStrings section as you want
The page in Listing 9.5 includes a SqlDataSource that uses the Movies connection string
LISTING 9.5 ShowMovies.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<title>Show Movies</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:GridView
id=”grdMovies”
DataSourceID=”srcMovies”
Runat=”server” />
<asp:SqlDataSource
id=”srcMovies”
SelectCommand=”SELECT * FROM Movies”
ConnectionString=”<%$ ConnectionStrings:Movies %>”
Runat=”server” />
</div>
</form>
</body>
</html>
The expression <%$ ConnectionStrings:Movies %> is used to represent the connection
string This expression is not case-sensitive
Rather than add a connection string to your project’s web configuration file, you can add
the connection string to a web configuration file higher in the folder hierarchy For
example, you can add the connection string to the root Web.Config file and make it
avail-able to all applications running on your server The root Web.Config file is located at the
following path:
C:\WINDOWS\Microsoft.NET\Framework\[v4.0.30319]\CONFIG
Trang 5Encrypting Connection Strings
You can encrypt the <connectionStrings> section of a web configuration file For
example, Listing 9.6 contains an encrypted version of the Web.Config file that was created
in Listing 9.4
LISTING 9.6 Web.Config
<?xml version=”1.0”?>
<configuration>
<protectedData>
<protectedDataSections>
<add name=”connectionStrings” provider=”RsaProtectedConfigurationProvider”
inheritedByChildren=”false” />
</protectedDataSections>
</protectedData>
<connectionStrings>
<EncryptedData Type=”http://www.w3.org/2001/04/xmlenc#Element”
xmlns=”http://www.w3.org/2001/04/xmlenc#”>
<EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc
#tripledes-cbc” />
<KeyInfo xmlns=”http://www.w3.org/2000/09/xmldsig#”>
<EncryptedKey Recipient=”” xmlns=”http://www.w3.org/2001/04/xmlenc#”>
<EncryptionMethod Algorithm=”http://www.w3.org/2001/04/xmlenc#rsa-1_5” />
<KeyInfo xmlns=”http://www.w3.org/2000/09/xmldsig#”>
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>MPLyXy7PoZ8E5VPk6K/azkGumO5tpeuWRzxx4PfgKeFwFccKx/
8Zc7app++0
4c/dX7jA3uvNniFHTW6eKvrkLOsW2m6MxaeeLEfR9ME51Gy5jLa1KIXfTXKuJbXeZdiwrjCRdIqQpEj4fGZvr
3KkwI5HbGAqgK4Uu7IfBajdTJM=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
<CipherValue>CgnD74xMkcr7N4fgaHZNMps+e+if7dnEZ8xFw07kOBexaX+KyJvqtPuZiD2hW
Dpqt5EOw6YM0Fs2uI5ocetbb74+d4kfHorC0bEjLEV+zcsJVGi2dZ80ll6sW+Y99osupaxOfrL3ld3mphM
Yrpcf+xafAs05s2x7H77TY01Y1goRaQ77tnkEIrQNQsHk/5eeptcE+A8scZSlaolFRNSSCdyO1TiKjPHF+
MtI/8qzr2T6yjYM5Z+ZQ5TeiVvpg/6VD7K7dArIDmkFMTuQgdQBSJUQ23dZ5V9Ja9HxqMGCea9NomBdhGC
0sabDLxyPdOzGEAqOyxWKxqQM6Y0JyZKtPDg==</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
</configuration>
Trang 6The contents of the <connectionStrings> section are no longer visible However, an
ASP.NET page can continue to read the value of the Movie database connection string by
using the <%$ ConnectionStrings:Movie %> expression
The easiest way to encrypt the <connectionStrings> section is to use the aspnet_regiis
command-line tool This tool is located in the following folder:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 \
Executing the following command encrypts the <connectionStrings> section of a
Web.Config file located in a folder with the path c:\Websites\MyWebsite:
aspnet_regiis -pef connectionStrings “c:\Websites\MyWebsite”
The -pef option (Protect Encrypt Filepath) encrypts a particular configuration section
located at a particular path
You can decrypt a section with the -pdf option like this:
aspnet_regiis -pdf connectionStrings “c:\Websites\MyWebsite”
NOTE
Web configuration encryption options are discussed in more detail in Chapter 34,
“Configuring Applications.”
Executing Database Commands
In this section, you learn how to represent and execute SQL commands with the
SqlDataSource control In particular, you learn how to execute both inline SQL statements
and external stored procedures You also learn how to capture and gracefully handle errors
that result from executing SQL commands
Executing Inline SQL Statements
You can use the SqlDataSource control to represent four different types of SQL
commands The control supports the following four properties:
SelectCommand
InsertCommand
UpdateCommand
DeleteCommand
Trang 7You can assign any SQL statement to any of these properties For example, the page in
Listing 9.7 uses all four properties to enable selecting, inserting, updating, and deleting
records from the Movies database table (see Figure 9.3)
FIGURE 9.3 Executing inline SQL commands
LISTING 9.7 ShowInlineCommands.aspx
<%@ Page Language=”C#” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN”
“http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” >
<head id=”Head1” runat=”server”>
<style type=”text/css”>
.detailsView
{
margin:0px auto;
border:solid 4px black;
background-color:white;
}
.detailsView td
{
padding:8px;
Trang 8}
html
{
background-color:silver;
font-family:Georgia, Serif;
}
a
{
color:blue;
text-decoration:none;
}
</style>
<title>Show Inline Commands</title>
</head>
<body>
<form id=”form1” runat=”server”>
<div>
<asp:DetailsView
id=”dtlMovies”
DataSourceID=”srcMovies”
DataKeyNames=”Id”
AllowPaging=”true”
AutoGenerateEditButton=”true”
AutoGenerateInsertButton=”true”
AutoGenerateDeleteButton=”true”
AutoGenerateRows=”false”
CssClass=”detailsView”
PagerSettings-Mode=”NumericFirstLast”
Runat=”server”>
<Fields>
<asp:BoundField DataField=”Id”
HeaderText=”Movie Id:” ReadOnly=”true” InsertVisible=”false” />
<asp:BoundField DataField=”Title” HeaderText=”Movie Title:” />
<asp:BoundField DataField=”Director” HeaderText=”Movie Director:” />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource
id=”srcMovies”
SelectCommand=”SELECT Id,Title,Director FROM Movies”
InsertCommand=”INSERT Movies (Title,Director,CategoryId,DateReleased)
VALUES (@Title, @Director,0,’12/15/1966’)”
UpdateCommand=”UPDATE Movies SET Title=@Title,
Director=@Director WHERE Id=@Id”
Trang 9DeleteCommand=”DELETE Movies WHERE Id=@Id”
ConnectionString=”<%$ ConnectionStrings:Movies %>”
Runat=”server” />
</div>
</form>
</body>
</html>
The page in Listing 9.7 contains a DetailsView control bound to a SqlDataSource control
You can click the Edit link to update an existing record, the New link to insert a new
record, or the Delete link to delete an existing record The DataBound control takes
advan-tage of all four SQL commands supported by the SqlDataSource control
Executing Stored Procedures
The SqlDataSource control can represent SQL stored procedures just as easily as it can
represent inline SQL commands You can indicate that a command represents a stored
procedure by assigning the value StoredProcedure to any of the following properties:
SelectCommandType
InsertCommandType
UpdateCommandType
DeleteCommandType
You can create a new stored procedure in Visual Web Developer by opening the Database
Explorer window, expanding a Data Connection, right-clicking Stored Procedures, and
clicking Add New Stored Procedure (see Figure 9.4)
The stored procedure in Listing 9.8 returns a count of the number of movies in each
movie category
LISTING 9.8 CountMoviesInCategory
CREATE PROCEDURE CountMoviesInCategory
AS
SELECT Name As Category, Count(*) As Count
FROM Movies
INNER JOIN MovieCategories
ON CategoryId = MovieCategories.Id
GROUP BY Name
The page in Listing 9.9 uses the CountMoviesInCategory stored procedure to display a
report with a GridView control (see Figure 9.5)
Trang 10FIGURE 9.4 Creating a new stored procedure in Visual Web Developer
FIGURE 9.5 Showing count of movies in category