1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu ASP.NET 1.1 Insider Solutions- P9 ppt

50 351 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 50
Dung lượng 0,98 MB

Nội dung

The text entered into the text box has added an extra test to the WHERE clause, and this test will be true for every row in the table; therefore, all the rows are returned. If, for example, you were collecting a username and password from a visitor and creating a SQL statement this way, you could find that your system is open to attack from this type of value entered by a user. For example, you might construct the SQL statement for such a process by using code like this: sSQL = “SELECT UserID FROM Users WHERE UserID = ‘“ & txtUser.Text & “‘ AND Password = ‘“ & txtPassword.Text & “‘“ In theory, this will return a row only when the user ID and password match the entries in the database. However, by using the technique just demonstrated, a visitor could contrive to have the following SQL statement executed: SELECT UserID FROM Users WHERE UserID = ‘johndoe’ AND Password = ‘secret’ or ‘1’ = ‘1’ This would return a non-empty rowset, and if you only check whether there are any rows returned, you might find that your security has been breached. However, if you enter the same text into the second text box in the sample page and click the second Go button to execute the SQL string with the value as a parameter, you’ll see that no rows are returned (see Figure 10.4). 10 Relational Data-Handling Techniques 388 FIGURE 10.4 The result of entering a mali- cious string for the parameter to a SQL statement. To understand why no rows are returned in this example, you can open the Profiler utility (by selecting Start, Microsoft SQL Server, Profiler) and trace the actions taken in the database. In this case, this is the instruction that SQL Server executes: exec sp_executesql N’SELECT CustomerID, CompanyName, City, Country FROM Customers WHERE CustomerID LIKE @CustomerID’, N’@CustomerID nvarchar(4000)’, @CustomerID = N’’’ or ‘’1’’=’’1’ In other words, SQL Server is passing the SQL statement and the parameter separately to the system stored procedure named sp_executesql , and it is specifying that the parameter is a 14 0672326744 CH10 5/4/04 12:23 PM Page 388 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 389 Using Parameters with SQL Statements and Stored Procedures character string ( nvarchar ). This string does not match the value in the CustomerID column of any row, so no rows are returned. It Gets Even Worse… The problem with the literal construction of the SQL statement described in the preceding section actually leaves you open to risks that are even more serious than you might think. For example, if you enter the following text into the first text box and execute it, you’ll see that the SQL statement shown in Figure 10.5 is used: ‘; update customers set city=’here!’ where customerID like ‘BOLID In fact, this is a batch statement that contains two separate SQL statements. The first one fails to find any rows that match the empty string in the WHERE clause, but then the second one is executed, and it updates the table. How to Use SQL Profiler To use SQL Profiler, open it from the Start menu or the Tools menu in Enterprise Manager and select File, New Trace to connect to your database. In the Trace Properties dialog that appears, select the Events tab and make sure that the complete set of actions for the Stored Procedure entry in the list of available TSQL event classes (displayed in the right-hand list) is selected. Then click Run, and you’ll see the statements that are being executed appear in the main Profiler window. FIGURE 10.5 A malicious value that updates the source table in the database. If you now change the value in the first text box and display the rows for customers whose IDs start with BO , you’ll see that the first one has been updated (see Figure 10.6). However, if you try this with the second text box, you’ll find that—as before—the process has no effect on the origi- nal data. The value that is entered and passed to SQL Server as a parameter simply fails to match any existing rows in the table, and nothing is changed or returned. One consolation is that the attack could be worse. For example, your malicious visitor could have entered this instead: ‘; drop database Northwind This deletes the database altogether. (The double hyphen at the end is a rem or comment marker that forces SQL Server to ignore the final apostrophe that gets added to the statement batch.) So if you construct SQL statements dynamically in your code and there’s any risk at all that the values you use might contain something other than you expect, you should always use parame- ters to build the SQL statement. In fact, it’s not a bad idea to do it every time! 14 0672326744 CH10 5/4/04 12:23 PM Page 389 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. The Code for Adding Parameters The code used in the sample page shown in Figures 10.1 through 10.6 contains two routines— one for each of the two Go buttons in the page. The first one builds the SQL statement in literal fashion, using the following: Dim sSQL As String = “SELECT CustomerID, CompanyName, City, “ _ & “Country FROM Customers “ _ & “WHERE CustomerID LIKE ‘“ & sParam & “‘“ In this case, sParam is the value extracted from the first text box on the page. This SQL statement is then executed and the result is assigned to the DataSource property of the DataGrid control on the page in the usual way. The second routine, which runs when the second Go button is clicked, works a little differently from the first. Listing 10.1 shows the complete routine. After collecting the value from the second text box, the routine declares the SQL statement. However, this time, the WHERE clause contains a parameter named @CustomerID : “WHERE CustomerID LIKE @CustomerID” LISTING 10.1 A Routine to Execute a SQL Statement with a Parameter Sub UseParamValue(sender As Object, e As EventArgs) ‘ get input value from TextBox Dim sParam As String = txtParam.Text ‘ declare SQL statement containing parameter Dim sSQL As String = “SELECT CustomerID, CompanyName, City, “ _ & “Country FROM Customers “ _ & “WHERE CustomerID LIKE @CustomerID” ‘ get connection string, create connection and command Dim sConnect As String = _ ConfigurationSettings.AppSettings(“NorthwindSqlClientConnectString”) 10 Relational Data-Handling Techniques 390 FIGURE 10.6 The result of executing the batch command shown in Figure 10.5. 14 0672326744 CH10 5/4/04 12:23 PM Page 390 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 391 Using Parameters with SQL Statements and Stored Procedures Dim oCon As New SqlConnection(sConnect) Dim oCmd As New SqlCommand(sSQL, oCon) Try ‘ specify query type, add parameter and open connection oCmd.Parameters.Add(“@CustomerID”, sParam) oCmd.CommandType = CommandType.Text oCon.Open() ‘ execute query and assign result to DataGrid dgr1.DataSource = oCmd.ExecuteReader() dgr1.DataBind() ‘close connection afterwards oCon.Close() ‘ display SQL statement in page and show hint lblResult.Text = “Executed: “ & sSQL lblHint.Visible = True Catch oErr As Exception ‘ be sure to close connection if error occurs ‘ can call Close more than once if required - no exception ‘ is generated if Connection is already closed oCon.Close() lblResult.Text = “<font color=’red’><b>ERROR: </b>” _ & oErr.Message & “</font>” End Try End Sub Next, you create the Connection instance and Command instance as usual. Before executing the SQL statement, however, you have to add a parameter to the Command instance to match the parame- ter declared within the SQL statement. The sample code uses the simplest override of the Add method for the Parameters collection of the Command instance and specifies the name and value of the parameter. The data type of the variable is automatically used to set the data type of the parameter—in this case, a String data type, which means that the parameter will be treated as being of type nvarchar ( System.Data.SqlDbType.NVarChar ) when SQL Server processes it. LISTING 10.1 Continued 14 0672326744 CH10 5/4/04 12:23 PM Page 391 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Notice also that you still have to use the value Text for the CommandType property of the Command instance because this is still a SQL statement and not a stored procedure. ( Text is the default, so you could, in fact, omit it altogether.) Ordering of Stored Procedures and Query Parameters A parameter-related issue can cause problems if you are not aware of it. It concerns the way that the different .NET Framework data providers handle parameters when you specify them by name. The sample page shown in Figure 10.7 helps illustrate this issue. 10 Relational Data-Handling Techniques 392 Parameter Name Prefixes in SQL Server In databases other than SQL Server or Sybase databases, you use just a question mark ( ?) as the parameter placeholder. If there is more than one parameter, you use multiple ques- tion mark placeholders and you must add the parameters to the Parameters collection of the Command instance in the same order that the placeholders appear in the SQL state- ment. The names of the parameters are ignored in this case. You can use this same syntax with SQL Server and Sybase as well, although the named parameter technique is usually more readable and less error prone. FIGURE 10.7 The ordering of stored proce- dure parameters that are specified by name. The sample page uses two stored procedures—one in SQL Server and one in an Access database—and executes them by using the various data providers that are part of the .NET Framework. The SQL Server stored procedure is as follows: CREATE PROCEDURE ParamOrderProc @Param1 varchar (10) = ‘Default1’, @Default varchar (10) = ‘Default2’, @Param2 varchar (10) = ‘Default3’, @Param3 varchar (10) = ‘Default4’ AS SELECT @Param1 + ‘, ‘ + @Default + ‘, ‘ + @Param2 + ‘, ‘ + @Param3 14 0672326744 CH10 5/4/04 12:23 PM Page 392 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 393 Using Parameters with SQL Statements and Stored Procedures This SQL Server stored procedure simply collects the values of the four parameters you provide when the stored procedure is executed, and it returns a character string that concatenates their values together. However, the point here is that they are all optional parameters, which means that not all of them must be specified when you execute the stored procedure. If the code that executes the procedure does not provide a value for one of the parameters, the default value specified within the stored procedure is used instead. Unfortunately, however, Access doesn’t support optional parameters, so the Access query used in the sample page has only three parameters and no default values: PARAMETERS Param1 Text(10), Param2 Text(10), Param3 Text(10); SELECT [Param1] + ‘, ‘ + [Param2] + ‘, ‘ + [Param3] AS Expr1; The strange effects shown in Figure 10.7 come about because when you call the stored proce- dure, you add the parameters in a different order from which they are defined in the stored procedures: oCmd.Parameters.Add(“@Param1”, “Value1”) oCmd.Parameters.Add(“@Param3”, “Value3”) oCmd.Parameters.Add(“@Param2”, “Value2”) The result shown in Figure 10.7 proves that with the exception of the SqlClient classes, the names you provide for parameters have no effect. They are ignored, and the parameters are passed to the stored procedure by position and not by name. You get back the three values in the same order as you specified them, even though the parameters’ names don’t match. However, with the SqlClient classes, the result is different. With these classes, parameters are passed by name, so you get back the values in an order that matches the order within the Parameters collection. The order in which you add them to the Parameters collection doesn’t matter; each one will match up with the corresponding named parameter in the stored procedure. Using Default Values in a Stored Procedure The previous example uses a stored procedure containing optional parameters. When you declare a parameter in a stored procedure in SQL Server and most other enterprise-level database systems, you can provide a default value for the parameter. In fact, it is required because this is how the database knows that it is an optional parameter. Without a default value, you’ll get an error if you call the procedure without providing a value for that parameter. Installing the Stored Procedure for This Example A SQL script named ParamOrderProc.sql is provided in the databases subfolder of the samples you can download for this book (see www.daveandal.net/books/6744/). You can use this script to create the stored procedure for the example. For SQL Server, you open Query Analyzer from the SQL Server section of your Start menu, select the Northwind data- base, and then open the script file and execute it. You must have owner or administrator permission to create the stored procedure. 14 0672326744 CH10 5/4/04 12:23 PM Page 393 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. By taking advantage of sensible defaults for your parameters, you can simplify the data access code you have to write in your ASP.NET pages and data access components. Listing 10.2 shows the stored procedure used in the sample page for this section of the chapter. It is designed to update rows in the Orders table of the Northwind sample database, and you can see that it takes 12 parameters. LISTING 10.2 A Stored Procedure That Provides Sensible Default Values CREATE PROCEDURE ParamDefaultProc @OrderID int, @CustomerID nchar(5), @OrderDate datetime = NULL, @RequiredDate datetime = NULL, @ShippedDate datetime = NULL, @ShipVia int = 1, @Freight money = 25, @ShipName nvarchar(40) = NULL, @ShipAddress nvarchar(60) = NULL, @ShipCity nvarchar(15) = NULL, @ShipPostalCode nvarchar(10) = NULL, @ShipCountry nvarchar(15) = NULL AS IF @OrderDate IS NULL BEGIN SET @OrderDate = GETDATE() END IF @RequiredDate IS NULL BEGIN RAISERROR(‘Procedure ParamDefaultProc: you must provide a value for the RequiredDate’, 1, 1) WITH LOG RETURN END IF @ShipName IS NULL BEGIN SELECT @ShipName = CompanyName, @ShipAddress = Address, @ShipCity = City, @ShipPostalCode = PostalCode, @ShipCountry = Country FROM Customers WHERE CustomerID = @CustomerID END 10 Relational Data-Handling Techniques 394 Using Optional Parameters in a Stored Procedure Optional parameters will only work really successfully when you use the SqlClient data provider because none of the other data providers (as discussed earlier in this chapter) pass parameters by name. To use other data providers, which pass parameters by position, you would have to make sure that the optional parameters are located at the end of the list and provide values for all the parame- ters up to the ones that you want to use the default values. BEST PRACTICE 14 0672326744 CH10 5/4/04 12:23 PM Page 394 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 395 Using Parameters with SQL Statements and Stored Procedures UPDATE Orders SET OrderDate = @OrderDate, RequiredDate = @RequiredDate, ShippedDate = @ShippedDate, ShipVia = @ShipVia, Freight = @Freight, ShipName = @ShipName, ShipAddress = @ShipAddress, ShipCity = @ShipCity, ShipPostalCode = @ShipPostalCode, ShipCountry = @ShipCountry WHERE OrderID = @OrderID The first 2 parameters, the order ID and the customer ID, are required. They are used to select the correct rows in the Orders and Customers tables within the stored procedure. However, the remaining 10 parameters are all optional. Notice that a couple of them are set to sensible default values (the freight cost and shipper ID), but the remainder are set to NULL by default. Inside the stored procedure, the code can figure out what to do if the user doesn’t provide values for some of the parameters. For example, if the order date is not specified, the obvious value to use is the current date, which is provided by the GETDATE function in SQL Server. All you have to do is test for the parameter being NULL ( IF @OrderDate IS NULL ). Writing to the Event Log from SQL Server If the user doesn’t provide a value for the RequiredDate parameter when he or she executes the stored procedure, you want to prevent the update and flag this as an invalid operation. You can do this by calling the RAISERROR method in SQL Server and providing the error message that will be returned to the user. By adding the WITH LOG suffix, you force SQL Server to write a message to its own error log file and into the Application section of Windows Event Log as well. The values used for the RAISERROR method are the message to write to the error and event logs, the severity level (which should be between 0 and 18 for non-system-critical messages), and an arbitrary state value that must be between 1 and 127. It’s also possible to use the RAISERROR method to raise system-defined messages or custom messages stored in the SQL Server sysmessages table. SQL Server’s Books Online contains more details. After executing the RAISERROR method, the sample page’s code simply returns from the stored procedure without updating the database row. Providing a Default Shipping Address The sample database contains details of the existing customers in the Customers table, so it would seem sensible that when a new order is added, the customer’s address details are used by default. In this case, you’re updating order rows rather than adding them, but the code still demonstrates a technique you could use when inserting rows. If the user does not provide a value for the @ShipName parameter (the name of the order recipi- ent), the stored procedure collects the values for all the address columns from the Customer table, using the CustomerID value provided in the mandatory second parameter to the stored proce- dure. LISTING 10.2 Continued 14 0672326744 CH10 5/4/04 12:23 PM Page 395 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Then, finally, the stored procedure executes a SQL statement with a combination of the values that were specified for the parameters, specified as defaults, or calculated within the stored procedure code. The sample page shown in Figure 10.8 uses this stored procedure. It contains a series of controls where you can enter the values for the parameters and specify whether they are to be set. If a check box is not set, that parameter will not be added to the Parameters collection of the Command instance, so the default parameter value will be used within the stored procedure. 10 Relational Data-Handling Techniques 396 FIGURE 10.8 The sample page that uses the stored procedure with optional parameters. The right-hand column of the page shows the values currently in the row in the database (for columns that can be edited). When you first load the page, this column is empty. You’ll see that it is populated after you execute the stored procedure, so you can tell what effects your settings have had on the row. The Code for the Stored Procedure Default Values Sample Page The code used for the sample page contains an event handler routine named ExecuteSproc that runs when the Execute button is clicked. Listing 10.3 shows the relevant sections of this code. After you create the Connection and Command instances and specify that you’re working with a stored procedure, you add the two mandatory parameters (the values for which are specified in page-level variables). The Sample Page Sets Some of the Values to Sensible Defaults By default, the sample page sets the check box for the RequiredDate parameter and fills in some suggested values for this and the other parameters. Even though RequiredDate is an optional parameter, a value must be provided to prevent an error from being reported within the procedure. You can click the Show button on the page to view the stored procedure code. 14 0672326744 CH10 5/4/04 12:23 PM Page 396 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 397 Using Parameters with SQL Statements and Stored Procedures Then you test each check box to see if it’s set. If it is set, you add a parameter to the Command instance with the value collected from the appropriate text box or drop-down list. After you’ve added all the parameters, you execute the stored procedure and then check whether any rows were updated. If no rows were updated, you display an error message in the page. LISTING 10.3 The ExecuteSproc Routine That Executes the Stored Procedure Sub ExecuteSproc(sender As Object, args As EventArgs) ‘ get connection string, create connection and command Dim sConnect As String = ConfigurationSettings.AppSettings( _ “NorthwindSqlClientConnectString”) Dim oCon As New SqlConnection(sConnect) Dim oCmd As New SqlCommand(“ParamDefaultProc”, oCon) Dim iRows As Integer Try ‘ specify query type, add parameters and execute query oCmd.Parameters.Add(“@OrderID”, iOrderID) oCmd.CommandType = CommandType.StoredProcedure oCmd.Parameters.Add(“@CustomerID”, sCustomerID) If chkOrderDate.Checked Then oCmd.Parameters.Add(“@OrderDate”, _ DateTime.Parse(txtOrderDate.Text)) End If If chkRequiredDate.Checked Then oCmd.Parameters.Add(“@RequiredDate”, _ DateTime.Parse(txtRequiredDate.Text)) End If If chkShippedDate.Checked Then oCmd.Parameters.Add(“@ShippedDate”, _ DateTime.Parse(txtShippedDate.Text)) End If If chkShipVia.Checked Then oCmd.Parameters.Add(“@ShipVia”, _ Integer.Parse(lstShipVia.SelectedValue)) End If If chkFreight.Checked Then oCmd.Parameters.Add(“@Freight”, _ Decimal.Parse(txtFreight.Text)) End If If chkShipName.Checked Then oCmd.Parameters.Add(“@ShipName”, txtShipName.Text) End If If chkShipAddress.Checked Then 14 0672326744 CH10 5/4/04 12:23 PM Page 397 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... select Start, Programs, Administrative Tools, Microsoft NET Framework 1.1 Configuration and open the Assembly Cache section by clicking the link in the left pane of the window All the installed assemblies are listed in the right pane (see Figure 10.16) Writing Provider-Independent Data Access Code FIGURE 10.16 Using the NET Framework 1.1 Configuration utility The Page_Load event handler simply calls... DataList controls) We include this example after seeing a question on the ASP.NET groups as to whether it is possible to handle the changed events for controls located within the output of a DataGrid control and do anything useful with them When you use a DataGrid control or DataList control for inline editing of the data rows in ASP.NET, as demonstrated in Chapter 4, the usual technique for updating... the Provider-Independent Data Access Example ‘ assembly details for System.Data in version 1.1 Dim sFQName As String = “System.Data, Version=1.0.5000.0, “ _ & “Culture=neutral, PublicKeyToken=b77a5c561934e089” Sub Page_Load() ‘ display data using SqlClient classes first time If Not Page.IsPostback... the full metadata for each column, such as primary keys, default values, and constraints n When you intend to perform a subsequent update to the source data n When you are using sorting or paging in an ASP.NET DataGrid control For other tasks, especially simple server-side data binding, the subsequently lower processing and memory overhead of the DataReader class can substantially improve performance... then call its Unwrap method This instantiates the class and returns a reference to the resulting object instance To use these methods, you have to import the System.Runtime.Remoting namespace into your ASP.NET page, along with any namespaces for other classes that you use through static binding However, you don’t have to import the namespaces for the classes that you instantiate dynamically through the... in each row as a selector that the browser will not recognize (and therefore will ignore) But because it is part of the style attribute of the HTML element, it is also part of the Style property of the ASP.NET control that implements the element You can set and read this value in your server-side code and have it persisted in the page, and it will be available following a postback An Alternative Approach . Param1 Text (10 ), Param2 Text (10 ), Param3 Text (10 ); SELECT [Param1] + ‘, ‘ + [Param2] + ‘, ‘ + [Param3] AS Expr1; The strange effects shown in Figure 10 .7. nvarchar ( System.Data.SqlDbType.NVarChar ) when SQL Server processes it. LISTING 10 .1 Continued 14 0672326744 CH10 5/4/04 12 :23 PM Page 3 91 Please purchase PDF Split-Merge on www.verypdf.com

Ngày đăng: 21/01/2014, 09:20

TỪ KHÓA LIÊN QUAN