Presentation is loading. Please wait.

Presentation is loading. Please wait.

11 Updating a Database Table Textbook Chapter 14.

Similar presentations


Presentation on theme: "11 Updating a Database Table Textbook Chapter 14."— Presentation transcript:

1 11 Updating a Database Table Textbook Chapter 14

2 22 Objectives You will be able to Write C# code to update a database table from user input.

3 3 SQL Injection Attacks Last class we looked briefly at SQL Injection Attacks. General defensive measure: scan for single quotes in user input and replace them by pairs of single quotes. Student Ryan Wheeler informed me of a class of attacks where this measure fails: SQL Smuggling Attacks Described in http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf http://www.comsecglobal.com/FrameWork/Upload/SQL_Smuggling.pdf November 2007

4 4 SQL Injection Attacks The "ironclad rule" still applies (all the more so): Never splice user input into a command string (in ADO.NET). Use a command parameter instead. Stored procedures are another effective mechanism applicable to most database systems. Permit the use of parameters. But have some vulnerabilites described in the SQL Smuggling paper.

5 5 Overview for Today We will extend the Address Lookup app from last class to permit the user to update database table entries, delete entries, and add new entries.

6 6 Getting Started Download the Address Lookup app from last class: http://www.cse.usf.edu/~turnerr/Web_Application_Design/ Downloads/2012_06_14_In_Class/ http://www.cse.usf.edu/~turnerr/Web_Application_Design/ Downloads/2012_06_14_In_Class/ Drill down to website folder Rename website folder Address_Update Open VPN connection if necessary. Open website folder, Address_Update, in Visual Studio Open web.config and put your own username, database name, and password into the connection string. Build and run.

7 7 Default.aspx

8 8 App in Action

9 9 Update The user can modify the TextBoxes but there is no way to write the updated entries back to the database. Add an Update button below the table. Initially disabled. Enabled only when something has been changed.

10 10 Update Button

11 11 Update Button Event Handler Double click on the Update Button to add an event handler. Fill in a stub.

12 12 Detect Changes Double click on one of the result TextBoxes. Visual Studio creates an empty event handler for TextChanged.

13 13 Use Same Event Handler for All TextBoxes Change the name to tbXXX_Text_Changed In Source View add this event handler to all result TextBoxes. Also set AutoPostBack to True Set btnUpdate.Enabled to false in btnLookup_Click event handler.

14 14 Text Changed Event Handlers Try it!

15 15 Successful Lookup Update button is disabled. Change any textbox.

16 16 TextBox Changed What's going on here? Why did the address disappear?

17 17 TextBox Changed There was a postback as soon as we changed an input. We needed this in order to enable the Update button. The Page_Load event handler cleared all of the Textboxes. We wanted this to that results from a previous lookup would not stay on the page after an unsuccessful lookup.

18 18 Solution Clear the results in the Lookup button click event handler when the lookup is unsuccessful. Not in Page_Load.

19 19 New Page_Load

20 20 New Lookup Button Click Handler Try again.

21 21 Zip Code Changed Click "Update Database" Modify Zip code.

22 22 Update Database Clicked

23 23 Lookup Failure Try entering address data.

24 24 Zip Code Modified Update Database is enabled!

25 25 A Flaw

26 26 A Flaw User should not be able to update the database unless lookup was successful. Results TextBoxes should be disabled if lookup was unsuccessful. Update Database button should also be disabled.

27 27 Updated Lookup Click Handler

28 28 Disable_Results_TextBoxes protected void Disable_Results_TextBoxes() { tbLastName.Enabled = false; tbFirstName.Enabled = false; tbAddress1.Enabled = false; tbAddress2.Enabled = false; tbCity.Enabled = false; tbState.Enabled = false; tbZipCode.Enabled = false; }

29 29 Enable_Results_TextBoxes protected void Enable_Results_TextBoxes() { tbLastName.Enabled = true; tbFirstName.Enabled = true; tbAddress1.Enabled = true; tbAddress2.Enabled = true; tbCity.Enabled = true; tbState.Enabled = true; tbZipCode.Enabled = true; }

30 30 Another Flaw Previous results should be cleared, and the TextBoxes disabled on TextChanged for the Input TextBox. Need AutoPostBack = True Double click on tbInput to add a TextChanged event handler.

31 31 tbInput_TextChanged Event Handler protected void tbInput_TextChanged(object sender, EventArgs e) { Clear_Results(); btnUpdate.Enabled = false; Disable_Results_TextBoxes(); } Try it! End of Section

32 32 Now the Real Work Add code to class Query to update the database. Will need a SQL Update command. Recall the Introduction to ADO.NET. http://www.cse.usf.edu/~turnerr/Web_Application_Design/072_Working_with_MS_SQL_Server.pdf Slide 46

33 33 Updating Multiple Fields http://www.cse.usf.edu/~turnerr/Web_Application_Design/072_Working_with_MS_SQL_Server.pdf Slide 46

34 34 A Design Dilemma Class Address knows nothing about SQL or ADO.NET. Class Query knows about SQL and ADO.NET Knows no details about class Address Where should we put the SQL Update function? Has to know details of both class Address and ADO.NET.

35 35 SQL Update Command Let's put the Update function in class Query. Keep class Address pure. Class Query already depends on class Address. Has function Get_Address. Knows the table name. Knows column Last_Name Add function Update_Address to class Query. Small increase in dependency on class Address.

36 36 Function Update_Address Pass in an updated Address object. Note that the ID cannot change. Everything else can change. Set up a connection to the database server just as we did for Get_Address. Set up a command object to do the update. Use ID field to specify table row to be updated. Set all other row items to the Address object property values, using command parameters.

37 37 The Update Function Create a SqlConnection object. Create a SqlCommand object. Set its Connection Property Set its CommandText property to the string for an UPDATE command. Use parameters for all table values. Use Address ID in the "where" clause. Invoke the command object's ExecuteNonquery method. Should affect exactly one row.

38 38 Function Update_Address public static void Update_Address( Address adr, out string error_msg) { SqlConnection cn = null; error_msg = ""; try { cn = Setup_Connection(); int nr_rows_affected = Perform_Update(cn, adr); if (nr_rows_affected != 1) { error_msg = "ERROR: Nr rows affected was " + nr_rows_affected; }...

39 39 Function Update_Address (continued)... catch (Exception ex) { error_msg = "ERROR updating table Addresses: " + ex.Message; } finally { if (cn != null) { cn.Close(); }

40 40 Function Perform_Update private static int Perform_Update(SqlConnection cn, Address adr) { string cmd_str = "UPDATE Addresses " + "SET Last_Name=@Last_name, " + "First_Name=@First_name, " + "Address1=@Address1, " + "Address2=@Address2, " + "City=@City, " + "State=@State, " + "Zip_Code=@Zip_code " + "WHERE ID=" + adr.Id; SqlCommand cmd = new SqlCommand(); cmd.Connection = cn; cmd.CommandText = cmd_str;...

41 41 Function Perform_Update (continued) cmd.Parameters.AddWithValue("@Last_name", adr.Last_name); cmd.Parameters.AddWithValue("@First_name", adr.First_name); cmd.Parameters.AddWithValue("@Address1", adr.Address1); cmd.Parameters.AddWithValue("@Address2", adr.Address2); cmd.Parameters.AddWithValue("@City", adr.City); cmd.Parameters.AddWithValue("@State", adr.State); cmd.Parameters.AddWithValue("@Zip_code", adr.Zip_code); int nr_rows_affected = cmd.ExecuteNonQuery(); return nr_rows_affected; } Build, but don't run. (We still don't have a call to Update_Address.)

42 42 The hardest part is done! But we have to pass an updated Address object to function Update_Address from the click event handler for btnUpdate. Where do we get the Address object? Where do we update its values?

43 43 The Address Object We might save the original Address object in ViewState. Must mark the class as "Serializable" Textbook page 259. We DO NOT have to provide the function to serialize the object. Update it from the TextBoxes when the user clicks the Update Database button.

44 44 The Address Object We have updated values for all of the properties of the Address object in the results TextBoxes. Everything except the ID. These values are automatically preserved in the ViewState. We could reconstruct the Address object, with the updated values, from the contents of the TextBoxes.

45 45 The Address Object We need a new constructor for class Address. ID as parameter. Initialize all fields as blank. Use the public properties to set the fields. Preserve just the ID as explicit member of ViewState

46 46 Class Address New constructor: public Address(int ID) { id = ID; last_name = ""; first_name = ""; address1 = ""; address2 = ""; city = ""; state = ""; zip_code = ""; }

47 47 Persist ID in ViewState In Default.aspx.cs protected void btnLookup_Click(object sender, EventArgs e) { string error_msg; Address adr = Query.Get_Address(tbInput.Text, out error_msg); if (adr == null) { Clear_Results(); Disable_Results_TextBoxes(); ViewState["ID"] = null; } else { Display_Results(adr); Enable_Results_TextBoxes(); ViewState["ID"] = adr.Id; } lblMessage.Text = error_msg; btnUpdate.Enabled = false; }

48 48 Button Update Click Handler protected void btnUpdate_Click(object sender, EventArgs e) { string error_msg = ""; int id = (int)ViewState["ID"]; Address adr = new Address(id); // Update the Address object from the TextBoxes. adr.Last_name = tbLastName.Text; adr.First_name = tbFirstName.Text; adr.Address1 = tbAddress1.Text; adr.Address2 = tbAddress2.Text; adr.City = tbCity.Text; adr.State = tbState.Text; adr.Zip_code = tbZipCode.Text; Query.Update_Address(adr, out error_msg); lblMessage.Text = error_msg; btnUpdate.Enabled = false; } Try it!

49 49 Successful Lookup Change Zip Code to 33619.

50 50 Zip Code Modified Click Update Database.

51 51 Check the Database Table

52 52 Summary We used ViewState to hold the Addess ID across postbacks. All other information for the current Address is automatically preserved in ViewState The user can update any part of the address in a TextBox. When the user asks to update the database we first reconstruct the Address object from the TextBoxes then pass the updated object to a function that updates the database table.

53 53 Summary Minimal Coupling Class Default is responsible for the user interface. Knows nothing about SQL. Knows the public methods of class Query. Knows the public methods and properties of class Address. Class Query is responsible for SQL operations. Knows the public methods and properties of class Address. Knows nothing about the user interface. Could be used in other apps or PC programs that use table Addresses. Class Address provides an object oriented interface to database table Addresses. Knows nothing about the user interface. Knows how to use a SqlDataReader.


Download ppt "11 Updating a Database Table Textbook Chapter 14."

Similar presentations


Ads by Google