Section 15.4. Data Binding


15.4. Data Binding

Various technologies have offered programmers the opportunity to bind controls to data so that as the data was modified, the controls responded automatically. As Rocky used to say to Bullwinkle, "But that trick never works." Bound controls often provided the developer with severe limitations in how the control looked and performed.

The ASP.NET designers set out to solve these problems and provide a suite of robust data-bound controls, which simplify display and modification of data, sacrificing neither performance nor control over the UI. In Version 2.0 they have expanded the list of bindable controls and provided even more out-of-the-box functionality.

In the previous section, you hardcoded radio buttons onto a form, one for each of three shippers in the Northwind database. That can't be the best way to do it; if you change the shippers in the database, you have to go back and rewire the controls. This section shows how you can create these controls dynamically and then bind them to data in the database.

You might want to create the radio buttons based on data in the database because you can't know at design time what text the buttons will have, or even how many buttons you'll need. To accomplish this, you'll bind your RadioButtonList to a data source.

Create a new web site called DisplayShippers and drag a RadioButtonList onto the form. This time, instead of choosing EditItems from the Common RadioButtonList Tasks, click Choose Data Source.... The Choose Data Source dialog opens, as shown in Figure 15-8.

Figure 15-8. Choosing a data source


Drop down the Select a data source menu, and choose <New Data Source>. You are then prompted to choose a data source from the datatypes on your machine. Select Database, and the Configure Data Source dialog box opens, as shown in Figure 15-9.

Figure 15-9. Configuring a data source


Choose New to configure a new data source, and the Connection Properties Dialog opens. Fill in the fields: choose your server name, how you want to log into the server, and the name of the database. Be sure to click Test Connection to test the connection. When everything is working, click OK as shown in Figure 15-10.

Figure 15-10. Setting the connection properties


After clicking OK, the connection properties will be filled in for the Configure Data Source dialog. Review them and if they are OK, click Next. On the next wizard page, name your connection (e.g., NorthWindConnectionString) if you want to save it to a configuration file that can be reused.

When you click Next, you'll have the opportunity to specify the columns you want to retrieve, or to specify a custom SQL statement or stored procedure for retrieving the data.

Drop the Table list and scroll down to shippers. Select the ShipperID and CompanyName fields, as shown in Figure 15-11.

Figure 15-11. Configuring the data source


While you are here you may want to click the AdvancedOptions button just to see what other options are available to you.


Click Next and test your query to see that you are getting back the values you expected, as shown in Figure 15-12.

Figure 15-12. Testing the query


It is now time to attach the data source you've just built to the RadioButtonList. A RadioButtonList (like most lists) distinguishes between the value to display (e.g., the name of the delivery service) and the value of that selection (e.g., the delivery service ID). Set these fields in the wizard, using the drop down, as shown in Figure 15-13.

Figure 15-13. Binding fields to the radio button control


You can improve the look and feel of the radio buttons by binding to the Shippers table, clicking the Radio Button list, and then setting the list's properties in the Properties window.

15.4.1. Examining the Code

Before moving on, there are a few things to notice. When you press F5 to run this application, it appears in a web browser, and the radio buttons come up as expected. Choose View Source and you'll see that what is being sent to the browser is simple HTML, as shown in Figure 15-14.

Figure 15-14. Examining the HTML that ASP.NET sends your browser


Notice that the HTML has no RadioButtonList; it has a table, with cells, within which are standard HTML input objects and labels. ASP.NET has translated the developer controls to HTML understandable by any browser.

A malicious user may create a message that looks like a valid post from your form, but in which he has set a value for a field you never provided in your form. This may enable him to choose an option not properly available (e.g., a Premier-customer option) or even to launch a SQL injection attack. You want to be especially careful about exposing important data such as primary keys in your HTML, and take care that what you receive from the user may not be restricted to what you provide in your form. For more information on secure coding in .NET, see http://msdn.microsoft.com/security/.


15.4.2. Adding Controls and Events

By adding just a few more controls, you can create a complete form with which users can interact. You will do this by adding a more appropriate greeting ("Welcome to Northwind"), a text box to accept the name of the user, two new buttons (Order and Cancel), and text that provides feedback to the user. Figure 15-15 shows the finished form.

Figure 15-15. The completed shipper form


This form won't win any awards for design, but its use will illustrate a number of key points about Web Forms.

I've never known a developer who didn't think he could design a perfectly fine UI. At the same time, I never knew one who actually could. UI design is one of those skills (such as teaching) that we all think we possess, but only a few very talented folks are good at it. As a developer, I know my limitations: I write the code, and someone else lays it out on the page and ensures that usability issues are reviewed.


Example 15-1 is the complete HTML for the .aspx file.

Example 15-1. The .aspx file
<%@ Page Language="C#" CompileWith="Shipper.aspx.cs"    ClassName="Shipper_aspx" %> <!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 runat="server">     <title>Choose Shipper</title> </head> <body>     <form  runat="server">     <table style="width: 166px; height: 33px">         <tr>             <td colspan="2" style="height: 20px">Welcome to NorthWind</td>         </tr>         <tr>             <td>Your name:</td>             <td><asp:TextBox  Runat=server></asp:TextBox></td>         </tr>         <tr>             <td>Shipper:</td>             <td>                 <asp:RadioButtonList                                            Runat="server"                      DataSource                     DataTextField="CompanyName"                      DataValueField="ShipperID">                 </asp:RadioButtonList>                    <asp:SqlDataSource                                          Runat="server"                     SelectCommand="SELECT [ShipperID], [CompanyName]                            FROM [Shippers]"                    ConnectionString=                    "<%$ ConnectionStrings:NorthWindConnectionString %>">                 </asp:SqlDataSource> <br />             </td>         </tr>         <tr>             <td><asp:Button  Runat=server Text="Order" /></td>             <td><asp:Button  Runat=server                                                Text="Cancel" /></td>         </tr>         <tr>             <td colspan="2"><asp:Label                     runat=server></asp:Label></td>         </tr>     </table>     </form> </body> </html>

When the user clicks the Order button, you'll check that the user has filled in his name, and you'll also provide feedback on which shipper was chosen. Remember, at design time you can't know the name of the shipper (this is obtained from the database), so you'll have to ask the listbox for the chosen name (and ID).

To accomplish all of this, switch to Design mode and double-click the Order button. Visual Studio will put you in the code-behind page, and will create an event handler for the button's Click event.

To simplify this code we will not validate that the user has entered a name in the text box. For more on the validation controls that make this simple, please see Programming ASP.NET (O'Reilly).


You add the event-handling code, setting the text of the label to pick up the text from the text box and the text and value from the RadioButtonList:

void btnOrder_Click( object sender, EventArgs e ) {        lblMsg.Text = "Thank you " + txtName.Text.Trim( ) + ".  You chose " +       rblShippers.SelectedItem.Text.ToString( ) + " whose ID is " +       rblShippers.SelectedValue.ToString( ); }

When you run this program you'll notice that none of the radio buttons is selected. Binding the list did not specify which one is the default. There are a number of ways around this, but the simplest is to override the OnLoad event and set the first radio button to be selected.

Return to Shipper.aspx.cs and type protected override. You will see a scrolling list of all the overrideable methods, properties, etc., as shown in Figure 15-16.

Figure 15-16. Overriding OnLoad


Start typing OnLoad; when it is highlighted press Tab. The stub for the overridden method is created, but its default body throws the NotImplementedException.

Delete the exception and replace it with this code:

rblShippers.SelectedIndex = 0;

This sets the RadioButtonList's first radio button to selected. The problem with this solution is subtle. If you run the application, you'll see that the first button is selected, but if you choose the second (or third) button and click OK, you'll find that the first button is reset. You can't seem to choose any but the first selection. This is because each time the page is loaded, the OnLoad event is run, and in that event handler you are (re-)setting the selected index.

The fact is that you only want to set this button the first time the page is selected, not when it is posted back to the browser as a result of the OK button being clicked.

To solve this, wrap the setting in an if statement that tests if the page has been posted back:

protected override void  OnLoad(EventArgs e) {     if ( !IsPostBack )     {        rblShippers.SelectedIndex = 0;     } }

When you run the page the IsPostBack property is checked. The first time the page is posted, this value is false and the radio button is set. If you click a radio button and then click OK, the page is sent to the server for processing (where the btnOrder_Click handler is run) and then the page is posted back to the user. This time the IsPostBack property is true, and thus the code within the if statement isn't run, and the user's choice is preserved, as shown in Figure 15-17.

Figure 15-17. The user's choice is preserved on postback


The complete code-behind form is shown in Example 15-2.

Example 15-2. Code-behind form for Shipper.aspx.cs
using System; using System.Data; using System.Configuration; using System.Text; 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; public partial class Shipper_aspx {    protected override void  OnLoad(EventArgs e)    {       if ( !IsPostBack )       {          rblShippers.SelectedIndex = 0;       }    }    void btnOrder_Click( object sender, EventArgs e )    {       lblMsg.Text = "Thank you " + txtName.Text.Trim( ) + ".  You chose " +          rblShippers.SelectedItem.Text.ToString( ) + " whose ID is " +          rblShippers.SelectedValue.ToString( );    } }

ASP 1.1 programmers take note: as mentioned earlier, the aspx.cs file is now greatly simplified. You can refer to items on the page (e.g., lblMsg) without declaring protected members, and all the designer-generated code is hidden, allowing you to focus exclusively on the logic of your application.




Programming C#(c) Building. NET Applications with C#
Programming C#: Building .NET Applications with C#
ISBN: 0596006993
EAN: 2147483647
Year: 2003
Pages: 180
Authors: Jesse Liberty

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net