ptg 384 <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. CHAPTER 9 Using the SqlDataSource Control From the Library of Wow! eBook ptg 385 Creating Database Connections 9 NOTE You can configure additional prov i d e r s 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> From the Library of Wow! eBook ptg 386 In 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” /> CHAPTER 9 Using the SqlDataSource Control From the Library of Wow! eBook ptg 387 Creating Database Connections 9 </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 From the Library of Wow! eBook ptg 388 Encrypting 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> CHAPTER 9 Using the SqlDataSource Control From the Library of Wow! eBook ptg 389 Executing Database Commands 9 The 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 From the Library of Wow! eBook ptg 390 You 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). CHAPTER 9 Using the SqlDataSource Control 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; From the Library of Wow! eBook ptg 391 Executing Database Commands 9 } 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” From the Library of Wow! eBook ptg 392 DeleteCommand=”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). CHAPTER 9 Using the SqlDataSource Control From the Library of Wow! eBook ptg 393 Executing Database Commands 9 FIGURE 9.4 Creating a new stored procedure in Visual Web Developer. FIGURE 9.5 Showing count of movies in category. From the Library of Wow! eBook . path c:WebsitesMyWebsite: aspnet_regiis -pef connectionStrings “c:WebsitesMyWebsite” The -pef option (Protect Encrypt Filepath) encrypts a particular configuration section located at a particular. <CipherData> <CipherValue>CgnD74xMkcr7N4fgaHZNMps+e+if7dnEZ8xFw07kOBexaX+KyJvqtPuZiD2hW Dpqt5EOw6YM0Fs2uI5ocetbb 74+ d4kfHorC0bEjLEV+zcsJVGi2dZ80ll6sW+Y99osupaxOfrL3ld3mphM Yrpcf+xafAs05s2x7H77TY01Y1goRaQ77tnkEIrQNQsHk/5eeptcE+A8scZSlaolFRNSSCdyO1TiKjPHF+. 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.