Chapter 19. Programming ASP.NET Applications

In the previous chapter, you saw how to use C# to create Windows applications; in this chapter, you’ll see how to use C# to create applications for the Web.

The .NET technology for building web applications (and dynamic web sites) is ASP. NET 2.0, which provides a rich collection of types for building web applications in its System.Web and System.Web.UI namespaces. There is a great deal to learn about ASP.NET, but much of it is language-independent. ASP.NET offers a rich suite of controls and related tools, including tools to validate data, display dates, present advertisements, interact with users, and so forth. Most of these require no coding whatsoever.

Tip

For more on the details of ASP.NET, please see Programming ASP.NET, Third Edition, by Jesse Liberty and Dan Hurwitz (O’Reilly, 2005).

The role of the C# programmer in ASP.NET development is to write the event handlers that respond to user interaction. Many of the event handlers will either add data to a database or retrieve data and make it available to the controls.

With Web Forms , the application is deployed to a web server, and users interact with the application through a standard browser.

Web Forms bring Rapid Application Development (RAD ) techniques (such as those used in Windows Forms) to the development of web applications. As with Windows Forms, you drag-and-drop controls onto a form and write the supporting code either inline or in code-behind pages.

Web Forms implement a programming model in which web pages are dynamically generated on a web server for delivery to a browser over the Internet. With Web Forms, you create an ASPX page with more or less static content consisting of HTML and Web Controls, and you write C# code to add additional dynamic content. The C# code runs on the server, and the data produced is integrated with the declared objects on your page to create an HTML page that is sent to the browser.

There are three critical points to pick up from the previous paragraph, and which you should keep in mind for this entire chapter:

In short, Web Forms are designed to be viewed through any browser, with the server generating the correct browser-compliant HTML. Just as with Windows Forms, you can create Web Forms in Notepad (or another editor of your choice) rather than in Visual Studio, but it makes no sense to do so and we will continue to use Visual Studio 2005 to enhance productivity and reduce errors.

Web Forms divide the user interface into two parts: the visual part or user interface (UI), and the logic that lies behind it. This is very similar to developing Windows Forms, as shown in Chapter 18. This is called code separation ; all examples in this book use code separation, though it is possible to write the C# code in the same file with the user interface.

The UI page is stored in a file with the extension .aspx. When you run the form, the server generates HTML sent to the client browser. This code uses the rich Web Forms types found in the System.Web and System.Web.UI namespaces of the .NET Framework Class Library (FCL ).

With Visual Studio, Web Forms programming couldn’t be simpler: open a form, drag some controls onto it, and write the code to handle events . Presto! You’ve written a web application.

On the other hand, even with Visual Studio, writing a robust and complete web application can be a daunting task; Web Forms offer a very rich UI and the number and complexity of Web Controls have greatly multiplied in recent years. User expectations about the look and feel of web applications have risen accordingly.

In addition, web applications are inherently distributed. Typically, the client will not be in the same building as the server. For most web applications, you must take network latency, bandwidth, and network server performance into account when creating the UI; a round trip from client to host might take a few seconds.

Web Forms are event-driven. An event represents the idea that “something happened.” An event is generated (or raised) when the user clicks a button, or selects from a ListBox, or otherwise interacts with the UI. Events can also be generated by the system starting or finishing work. For example, open a file for reading, and the system raises an event when the file has been read into memory.

The method that responds to the event is called the event handler. Event handlers are written in C# and are associated with controls in the HTML page through control attributes.

By convention, ASP.NET event handlers return void and take two parameters. The first parameter represents the object raising the event. The second, called the event argument, contains information specific to the event, if any. For most events, the event argument is of type EventArgs, which has no members and serves as a placeholder and as the base class for more specialized objects that provide properties needed by the event handler.

In web applications, most events are handled on the server and, therefore, require a round trip. ASP.NET supports only a limited set of events, such as button clicks and text changes. These are events that the user might expect to cause a significant change, as opposed to Windows events (such as mouse-over) that might happen many times during a single user-driven task.

To create the simple Web Form that will be used in the next example, start up Visual Studio .NET and select File → New Web Site . In the New Web Site menu , choose C# as your language, and choose ASP.NET Web Site as the template to use. Finally, locate your web site somewhere on your disk (at the bottom of the dialog), as shown in Figure 19-1.

Visual Studio creates a folder named Learning C Sharp Web in the directory you’ve indicated, and within that directory, it creates your Default.aspx page (for the User interface), Default.aspx.cs (for your code), and a Data directory (currently empty, but often used to hold data files).

Code-behind is the default coding model used by Visual Studio 2005. When a new web site is created, Visual Studio automatically creates two files: the content file, with a default name, such as Default.aspx, and a code-behind file with a matching name, such as Default.aspx.cs (assuming you are using C# as your programming language). If you change the name of the content file (highly recommended), the code-behind file will automatically assume the new name.

Let’s take a closer look at the .aspx and code-behind files that Visual Studio creates. Start by renaming Default.aspx to HelloWeb.aspx. To do this, close Default.aspx, and then right-click its name in the Solution Explorer. Choose Rename and enter the name HelloWeb.aspx. That renames the file, but not the class. To rename the class, right-click the .aspx page and choose View Code in the code page, then rename the class from _Default to HelloWeb. You’ll see a small line next to the name, as shown in Figure 19-2.

Click it and you’ll open the smart tag that allows you to rename the class. Click Rename “_default” to “HelloWeb,” and Visual Studio ensures that every occurrence of _Default is replaced with its new name, as shown in Figure 19-3.

You will be warned that references in “markup” will not be changed. This means that you must manually update the name of the class in the .aspx file:

    <%@ Page Language="C#" AutoEventWireup="true"
    CodeFile="HelloWeb.aspx.cs"Inherits="HelloWeb" %>

Within the HTML view of HelloWeb.aspx, you see an HTML form tag within the body of the page, like this:

    <form id="Form1" runat="server">

This tag specifies the form to use for your page. Web Forms assumes that you need at least one form to manage the user interaction, and creates one when you open a project. The attribute runat="server" within the form tag is the key to the server-side magic. Any tag that includes this attribute is considered a server-side control to be executed by the ASP.NET framework on the server. Visual Studio has placed div tags in the form to facilitate placing your controls and text.

Look for the title tag and change it to “Hello Web”—it makes the browser window look nicer, as you’ll see in just a moment.

Having created an empty Web Form, the first thing you might want to do is add some text to the page. By switching to HTML view, you can add script and HTML directly to the file just as you could with classic ASP. Adding the following line to the body segment of the HTML page (between the opening and closing div tags) will cause it to display a greeting and the current local time:

    Hello World! It is now <% = DateTime.Now.ToString(  ) %>

The <% and %> marks surround snippets of C# code. The = sign immediately following the opening tag causes ASP.NET to display the value, just like a call to Response.Write( )—that is, it writes directly to the HTML page. You could just as easily write the line as:

    Hello World! It is now
    <% Response.Write(DateTime.Now.ToString(  )); %>

Run the page by pressing F5 (or save it and navigate to it in your browser). You should see the string printed to the browser, as in Figure 19-4.

You can add Server Controls to a Web Form in three ways: by writing HTML into the HTML page, by dragging controls from the toolbox to the Design page, or by pro-grammatically adding them at runtime. For example, suppose you want to use buttons to let the user choose one of three shippers provided in the Northwind database. You can write the following HTML within the <div> elements, in the HTML window:

    <div>
     <asp:RadioButton GroupName="Shipper" id="Speedy"
       text = "Speedy Express" Checked="True" runat="server" />
     <asp:RadioButton GroupName="Shipper" id="United"
       text = "United Package" runat="server"/>
     <asp:RadioButton GroupName="Shipper" id="Federal"
       text = "Federal Shipping" runat="server" />
    </div>

The asp tags declare server-side ASP.NET controls that are replaced with normal HTML when the server processes the page. When you run the application, the browser displays three radio buttons in a button group; pressing one deselects the others.

You can create the same effect more easily by dragging three buttons from the Visual Studio toolbox onto the Form, or, to make life even easier, follow these steps:

  1. Switch to Design view.

  2. Drag a RadioButtonList control from the toolbox onto the form.

  3. Click on the control’s the smart tag to open it.

  4. Choose Edit Items to open theListItem Collection Editor dialog box.

  5. Click Add three times to add three radio buttons.

Each radio button is given the default name ListItem, but you may edit its text and value in the ListItem properties, where you can also decide which of the radio buttons is selected, as shown in Figure 19-6.

Click OK to close the editor and then switch back and forth between the Design and Source tabs to see the effect of your changes, as shown in Figure 19-7.

I’ve numbered a few areas of interest in Figure 19-7. Number 1 shows the RadioButtonList control in the toolbox. Number 2 shows the smart tag on the RadioButtonList control on the form. Number 3 shows that you are looking at the properties of the RadioButtonList control, which has been named RadioButtonList1 for you by Visual Studio 2005 (but of course, you are free to change that in the Properties window), and Number 4 shows that the current RepeatDirection property is set to Vertical (setting it to horizontal will lay out the radio buttons horizontally).

Server Controls

Web Forms offer two types of Server Controls. The first is server -side HTML controls . These are HTML controls that you tag with the attribute runat=Server. Although these work, we won’t spend time on them in this chapter.

Instead, we will focus on ASP.NET Server Controls[13] that Microsoft designed to augment and replace the standard HTML controls. Server Controls provide a more consistent object model and more consistently named attributes. For example, with traditional and server-side HTML controls, input is not handled consistently:

    <input type="radio">
    <input type="checkbox">
    <input type="button"><input type="text"><textarea>

Each input type behaves differently and takes different attributes, and text is handled with different types of controls depending on whether you want a single line or multi-line input. The Server Controls try to use attributes consistently. The Server Controls that correspond to the preceding HTML Server Controls are as follows:

    <asp:RadioButton>
    <asp:CheckBox>
    <asp:Button><asp:TextBox rows="1"><asp:TextBox rows="5">

When you use the Server Controls, ASP.NET translates them into ordinary HTML before sending the page back to the browser. What is seen on the browser is always industry-standard HTML and will run on virtually any browser by any manufacturer.

Various technologies have offered programmers the opportunity to bind controls to data so that as the data was modified, the controls responded automatically. Generally speaking, they made for great demos, but were of limited use to real programmers writing commercial applications. They tended to constrain the developer with severe limitations in how the control looked and performed. It came down to this: “If you want to do what we expect, it is wicked easy, but if you want to do anything else, may the Gods be kind.”

The ASP.NET designers set out to 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 hard-coded 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 you how to create these controls dynamically, binding them to data from the database.

Create a new web site called DisplayShippers and drag a RadioButtonList onto the form. Click on the smart tag, and then click on Choose Data Source .... The Choose Data Source dialog opens, as shown in Figure 19-8.

Drop down the Select a data source menu and choose <New Data Source>. You are prompted to choose a data source from the datatypes on your machine. Select Database, (you can specify a name, or use the default name of SqlDataSource1). Click OK and the Configure Data Source dialog box opens.

Choose New Connection to configure a new data source, and the Add Connection dialog box opens, offering you an opportunity to pick a server and to use either Windows or database authorization. Fill in the required information, and choose Northwind as your database name. Be sure to test the connection, as shown in Figure 19-9.

When you click OK, you’ll return to the Configure Data Source dialog. You can examine the connection string if you’d like or just press Next to go on to the next step, where you are asked if you’d like to save this connection in the application configuration file. Click Yes and give it a name without spaces, such as NorthwindConnectionString.

The next step is to specify either a stored procedure or SQL statement to use for your query, or to build your query by picking the table or view and then the columns you want, as shown in Figure 19-10.

When you click Next, you are brought to a dialog in which you can test the results of your query, which you can examine as shown circled in Figure 19-11.

When you click Finish, the data source is created. You are returned to the Data Source Configuration Wizard, where you will make three choices:

  1. The data source to use (in this case, you have only one)

  2. The data field to display in the radio button list

  3. The data field to use for the value

These choices are shown in Figure 19-12.

The distinction between the display field and the data field allows you to display the company name in the radio button list, but retrieve the actual shipper ID when processing the user’s request. Run the application (accept the offered Web.config file as previously) and note that the radio button list is dynamically populated with the three values from the database table.

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 19-13.

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.

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 19-14 shows the form.

This form won’t win any awards for design, but its use will illustrate a number of key points about Web Forms. Example 19-1 is the complete HTML for the .aspx file.

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.

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:

    protected 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 are 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 the Shipper.aspx.cs and type protected override. You will see a scrolling list of all the overrideable methods, properties, etc. Start typing the first letters of OnLoad, as shown in Figure 19-15.

When OnLoad is highlighted, press Tab to accept the method. 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 selects the first radio button in the RadioButtonList. 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 19-16.

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



[13] Some programmers also call these “ASP Controls” or “Web Controls.”