Chapter 3: ASP Server Controls – ASP.Net Web Developer's Guide

Chapter 3

ASP Server Controls

Introduction

ASP.NET supplies ASP.NET programmers with a much-needed solution to an age-old problem—HTML form controls. Up until .NET, ASP programmers had to move back and forth between HTML and ASP in order to provide interactivity between Web pages. This also meant that an ASP page was not as dynamic as it could be if it were done through Java or through some extensive JavaScript/Cascading Style Sheet (CSS) coding.

In short, ASP had the short end of the stick as far as Web interactivity went. With the advent of ASP server controls, all that will change. Imagine being able to do real-time value verification and having the Web page instantly spit out an error when someone tries to skip a required field. Imagine being able to dynamically replace data on a Web page without having to force the user to access another page or restart completely. With ASP.NET, all this and more is possible! The exercises illustrated in this chapter will demonstrate to you the power of ASP.NET.

Major Features of ASP.NET Server Controls

When you develop an ASP.NET Web Form, you can use the following type of controls:

 HTML Server Controls You can manipulate these controls at the server-side. Before dispatching a form to the client, the ASP Engine converts them to the equivalent HTML elements. These controls are included in the System.Web.UI.HtmlControls namespace.

 Web Server Controls (also known as Web Controls or ASP.NET Web Form Controls) These are the new generation’s controls developed by Microsoft. They have many useful built-in features, and a standard set of properties. In the HTML or .aspx file, these are typically referenced with an asp: prefix such as asp:Label, asp:Button, or asp:TextBox. Besides the form-type server controls such as labels, button, and dropdown, there are a number of special-purpose controls like the Calendar and AdRotator controls. The ASP Engine also maps these controls to standard HTML equivalent controls before dispatching the page to the client. These Web server controls are available in the System.Web.UI.WebControls namespace.

 Validation Controls This set of controls provides Rapid Application Development (RAD) features for automatically checking the specified validity of user inputs. These controls are available in the System.Web.UI.WebControls namespace.

 Custom Controls You can develop your own server controls by extending an existing control or group of controls to provide additional functionalities. There are two versions of custom controls:Web User Controls and Web Custom Controls. The Web User Controls are easy to develop, and are typically stored as .ascx files. The Web Custom Controls require in-depth knowledge of Object Oriented Programming and the Common Language Runtime (CLR). These are stored in compiled form as assemblies.

In this chapter we will provide an overview of these controls. Before we introduce you to the ASP.NET server controls, we need to focus your attention on a number of procedural issues involved in developing a Web form. These issues are the following: Collecting Data using HTML Forms, State-less ASP controls versus State-full ASP Net controls, the role of PostBack, and In-Page Code versus Code-Behind.

NOTE

In an IIS environment, the ASP and ASP.NET can run side by side. If you install ASP.NET, your existing ASP applications will continue running. The IIS uses the ASP Engine to process the .asp files, whereas it uses the ASP.NET Engine to process the .aspx files. Session states and application states are not shared between ASP and ASP.NET pages.

Collecting Data Using HTML Forms

HTML uses the Hypertext Transfer Protocol (HTTP) to transmit Web pages. When you enter a URL of a page in your browser, it sends an HTTP message to the server, requesting the desired page. This message is typically known as the Request message. If the desired page has a *.html or *.htm extension, the Web server simply retrieves the page from the server’s disk and sends it back to your computer (client) via a new HTTP message, known as the Response message. It is your browser that interprets the mark-up codes in the Response object and presents the page on your monitor.

In an HTML document, you can use an HTML form element to collect data from the user. Typically, other HTML elements like buttons, checkboxes, or textboxes are imbedded in an HTML form. It also provides an HTML Submit button in the form. With one click of the Submit button, the browser packages the user’s given data in a Request message and then sends it to the server. An HTTP message has two parts: the HTTP Header and the HTTP Body. Thus, the browser can package the user-given data in the Request object in one of two ways. It may augment the URL with the name-value pairs of submitted data. Alternatively, it can package the submitted data inside the body part of the Request message. Which of the alternative methods will it use. The answer depends on the specifications in the HTML form element. A typical form tag is shown in Figure 3.1.The Method parameter is used to specify the mode of data transmission. If it is “Get”, the browser sends the data in the header section of the HTTP message. If it is “Post”, the data are sent in the body section. The Action parameter can be used to request a specified html or other documents like .asp or .aspx files.

Figure 3.1 Major Parameters (Attributes) of an HTML Form Element

To demonstrate the data-passing mechanism using the Get method, we will present a simple example. Consider the Sample1.html document as shown in Figure 3.2, which is included on the CD that accompanies this book. In this code, we have included a HTML form named myForm. It has a Submit button, and a textbox. The user will enter a hobby and click the Submit button. On click of the Submit button, the browser will request the html document named Sample1.html and pass the submitted data to the server in the augmented URL. In this particular example, the browser will actually request the same html document (named Sample1.html). Figure 3.3 shows the URL of the requested form as submitted by the browser to the Web server. You will see that the browser has augmented the URL, and the new URL is http://ahmed2/Chapter3/sample1.html?txtHobby=Fishing. That means the data are submitted as a name=value pair in the URL itself. The first such pair is prefixed with a question mark.

Figure 3.2 A Simple Data Collection HTML Form (Sample1.html)

Figure 3.3 Submitting Data in the Augmented URL: Get Method

If we specify Method=“Post” in the form tag, the data are packaged as name-value pairs in the body section of the HTTP message. Unfortunately, we cannot have a peak inside the body section, and thus it cannot be shown. Once the data are submitted, what do we do with it.Well, that is where the server-side scripting comes into the scenario. We will briefly discuss the ASP.NET server-side processing in the next section.

Server-Side Processing in ASP.NET

An ASP.NET file has an *.aspx extension. Typically, it contains HTML elements, server-side codes and client-side codes. As shown in Figure 3.4, when a user requests an ASPX page, the server retrieves it from the disk and then sends it to the ASPX Engine for further processing. The ASPX Engine compiles the server side codes and generates the page class file. It then instantiates the class file and executes the instructions to develop the response object. During the execution stage, the system follows the programmatic instructions (in the server-side code) to process the data submitted by the user. Finally, the server transmits the response object to the client. In short, the major steps in processing a request for an ASPX page are as follows:

Figure 3.4 Major Steps in Serving an ASPX Page

1. The server receives a request for a desired ASPX page.

2. The server locates the page in the disk.

3. The server gives the page to the ASP.NET Engine.

4. The ASP.NET Engine compiles the page and generates the page class. If the class had already been loaded, it simply provides a thread to the running class instead of regenerating the class. During compilation, it may require other code classes, such as code-behind classes and component classes. These are assembled during this step.

5. The ASP.NET instantiates the class, performs necessary processing, and it generates the Response object.

6. The Web server then sends the Response object to the client.

Now that we know about the HTML Forms and Web server environment, we will start discussing the server controls. To demonstrate the basic principles of server controls, we will kick off this section by presenting a simple application using conventional HTML controls. Then we will develop the same application using the ASP.NET Web controls and highlight the major differences.

A Simple Application Using Conventional HTML Controls

As shown in Figure 3.5, we will display some flower names using conventional HTML controls. On click of a command button we will request the same form from the server. The code for this form is shown in Figure 3.6 and can be found on the CD that accompanies this book.

Figure 3.5 Conventional HTML Form and Controls

Figure 3.6 A Simple .aspx File Using Conventional HTML Controls (Conventiona1.aspx)

Once the form is displayed, we will select a flower from the list box, and either click on the Submit button or refresh the page. In both cases, the system will return the same form, but we will see that our selection has been lost. This is due to the state-less nature of HTTP protocol. On each request, the server serves the requested page, however, it does not remember the values of the controls assigned in its prior invocation. In ASP days, we had to include a good amount of codes to preserve the states of the controls. Well, ASP.NET has made life easier! It preserves the states of controls automatically.

A Simple Application Using ASP Server Controls

In this example, we will develop the same application using ASP.NET Server Controls. At this stage, we have two choices. We may either use HTML Server controls or Web Server controls. Just for the sake of experimentations, we will use the <asp:listbox> Web Server Control, and the <input type=“button”> HTML Server Control. Irrespective of which type of controls we use, we will need to add a new attribute in the tags for these controls. When we create an instance of these controls, we will specify its runat attribute to be “server” such as <asp:listbox id=“lstFlowers” runat=“server”/>. The output is shown in Figure 3.7. Its revised code is shown in Figure 3.8 and can be found on the CD that accompanies this book.

Figure 3.7 The Flower Selection Application Using ASP.NET Server Controls

Figure 3.8 The Code for ServerControl1.aspx (ServerControl1.aspx)

Once a flower is selected and the command button is clicked, the client will receive a new instance of the form from the server, however, the selected value of the list box will persist. This phenomenon is known as state-full. This is because the ASP.NET controls maintain their states in spite of the state-less nature of the HTTP protocol.

Mapping Server Controls and Preserving Their States

In our previous example, we have preserved the state of the list box. Of course, the ASP.NET framework has assisted us in doing so. Now, how does the system map the server controls, and how does it preserve the states of the controls. Answers to both of these questions are actually available in the source document received by the client. Once we run the application, we may view the source code received by our browser using the View | Source menu of Internet Explorer. The contents of the source code are shown in Figure 3.9. In this figure, please note that the system has mapped our asp:listbox control to a conventional HTML <select name=“ctrl1” size=“3”> tag. The system has also added an <input type=“hidden”> tag with many attributes.

Figure 3.9 The Source Code of the Document Received by the Browser

It is via this hidden field that the system transfers the user-given values to the server. In summary, the server controls are mapped to standard HTML controls, and the ASP.NET employs hidden fields to maintain the states of the controls.

Including Scripts in an .aspx File

So far our examples have been very simple, and we have not yet included any script in the examples. In the previous exercise (Figure 3.8), we have hard-coded the values of the list box in its definition. Suppose that we need to load the list box via code. We will need to do that when the values to be loaded are unknown during the design time, and would come from an external source like a text file, an XML document, or from a database query. Although we will not venture into the XML or database topics right now, it is still beneficial to know how to load the list box programmatically. This is what we will do in our next example.

Loading a List Box via Script

In this example we will accomplish two objectives. First, we will load the list box via code. Secondly, we will provide a command button. The user will select a flower and then click the button. On the click() event of the button we will display his or her selection. The output of the example is shown in Figure 3.10.

Figure 3.10 The Output Generated by Figure 3.11

The complete listing of the code is shown in Figure 3.11, which can also be found on the CD that accompanies this book. In the code, the following statements are of major interests:

Figure 3.11 ServerControl2.aspx (ServerControl2.aspx)

 We have added a Page Declaration:

    <%@ page language=“VB” debug=“true” % >

 At the initial stage, the debug=“true” helps us a lot by providing detailed explanations of our errors during the run-time. The debug=“true” specification drains the system’s resources, and hence, we should delete it from our finished work.

 We have defined an asp:button and “wired up” its click event with a sub-procedure named showSelection() as the following:

    <asp:button id=“btnSubmit” runat=“server” text=“Submit” onclick=“showSelection” />

 The list box is loaded in the Page_Load event as follows:

    As you can see from the previous code, we are setting “Tulip” as the default selection in the list box.

 Finally, we are displaying the selection in the showSelection procedure:

    Sub showSelection(sender As Object, e As EventArgs)

    lblMessage.Text =“You have selected ” + _

    lstFlowers.SelectedItem.Text

    End Sub

The code appears to be very simple. However, the code still has some intentional bugs. When we run this application, we will observe that the page behaves very erratically. First, irrespective of the selection we make, it will always display “You have selected Tulip”. Secondly, on repeated clicks of the command button, the list box will continue growing with duplicate entries. Now, that is a surprise, isn’t it.Let us try to figure out this strange behavior of the application in our next section!

Using the IsPostBack Property of a Page

An ASPX page is loaded upon each request. In our previous example, when we click the command button, it submits the form back to the server and requests the same page. This phenomenon is known as PostBack. The system will load the page again, and hence, the Page_Load event will take place on every request. That is why, if we run the code shown in Figure 3.11, our list box will keep on growing in size. This is also why the SelectedItem property of the list box will keep on being reset to “Tulip” on each post back.

In this case, we should rather load the list box only once during the first invocation of the page. Wait a minute! If we do not load the list box again, how would it get populated when the page is reloaded?. Well, therein lies the beauty of ASP.NET. The server controls automatically retain their values (state-full and not state-less), thus we do not need to load the list box repetitively on successive requests of the page. How do we achieve that?. In the Page_Load event, we may use the Page.IsPostBack property as shown in Figure 3.12. You can also find this code for Figure 3.12 (SeverControl3.aspx) on the accompanying CD.

Figure 3.12 Loading a List Box Correctly (ServerControl3.aspx)

Now, go ahead and replace the script in Figure 3.11 with the previous script shown in Figure 3.12. The application will work fine! The complete code for this application is available in ServerControl3.aspx in the CD.

AutoPostBack Attributes of Server Controls

In this section, we will illustrate an important behavior of certain server-side controls. Some server-side controls can generate automatic postbacks on selected events. That means, to submit a form, we may not have to wait until the user clicks the submit button. For example, the SelectedIndexChange event of an asp:ListBox is an event that is capable of triggering a postback. If we want this mechanism to work, we will have to set the AutoPostBack property of the List box to “True.”

To illustrate the AutoPostBack attribute of an asp control, we will revise our flower selection example. We will remove the Submit button (although we could have kept it, too, without any loss of functionality). We will set the AutoPostBack attribute of the list box to be True, and we will attach the showSelection VB function on its onSelectedIndexChanged attribute. When you run this form, every time you select a new flower, the system will display your selection in the label. We do not need the Submit button because the onSelectedIndexChanged event will generate a postback. The output of this application is shown in Figure 3.13, and its code is shown in Figure 3.14 (which is also available on the CD that accompanies this book).

Figure 3.13 A List Box with Its AutoPostBack Property Set to True

Figure 3.14 Complete Code (ServerControl4.aspx)

NOTE

While using the AutoPostBack attribute, we need to be careful. An AutoPostBack submits the form to the server; thus, the system will eventually slow down significantly if we use too many of these AutoPostBacks.

Structure of an ASP.NET Web Form

A Web Form is an ASP.NET technology that we use to create a programmable Web page. It can present information, using any markup language, to the user in any browser, and can use code on the server to implement application logic. In .NET documentation, Microsoft has outlined the following characteristics of a Web form:

 A Web form of your design can run on a specific browser of your choice, or it can run on any browser and automatically render the browser-compliant HTML.

 It is built on the Common Language Runtime, thereby providing a managed execution environment, type safety, inheritance, and dynamic compilation. It can be programmed in any CLR-supported language.

 It supports WYSIWYG editing tools and development tools such as VS.NET.

 It supports a rich set of controls that enables you to encapsulate page logic into reusable components and declaratively handle page events.

 It allows for separation between code and content on a page.

 It provides a set of state management features that preserves the view state of a page between requests.

As shown in Figure 3.15, a Web form may contain directives, server-side scripts, client-side scripts, static texts, Web controls, HTML controls, and many others. In the remainder of this section, we will provide an overview of ASP.NET Page directives.

Figure 3.15 Typical Contents of a Web Form

Page Directives

Page directives are used to set various attributes about a page. The ASP Engine and the compiler follow these directives to prepare a page. There are many kinds of directives. The most frequently ones are the following: @ Page, @ Import, @ Implements, @ Register, @ OutputCache and @ Assembly directives. These directives can be placed anywhere in a page, however, these are typically placed at the top. Table 3.1 briefly describes the major use of these directives.

Table 3.1

Page Directives and Their Functions

Page Directive Description and Example
@ Page We may use this directive to declare many page-related attributes about a particular page. For example, we use this directive to declare the language to be used in a page, such as <%@ Page Language= VB Debug= true %> page. There are numerous attributes of this directive. Some of the frequently used ones are these: AutoEventWireup, Buffer, ClientTarget, EnableSessionState, ErrorPage, Debug, Trace, TraceMode, and so on.
@ Import We use this directive to import a namespace in the page class file. For example, in the following directive, we are importing the System.Data.OleDb namespace in our page: <%@ Import Namespace=“System.Data.OleDb” %>.
@ OutputCache We can use this directive to specify how to cache the page. In the following example, we are setting the duration that a page or user control is output cached: <%@ OutputCache Duration=“10” /%>.
@ Register This directive is used to register a custom control in a page. In the following example, we are registering one of our user custom controls in page: <%@ Register tagprefix =“utoledo” tagname=“Time” Src=“TimeUserControl.ascx”%>.
@ Assembly We use this directive to link to an assembly to the current page or user control. The following example shows how to link to an assembly-named payroll: <%@ Assembly Name=“Payroll” %>.
@ Implements This directive enables us to implement an interface in our page. In the following example, we are implementing the IpostBackEventHandler interface in one of our user controls: <%@ Implements Interface=“System.Web.UI .IPostBackEventHandler” %>.

The Order of Event Execution

One of the novel offerings of ASP.NET is that it enables us to write server-side code to handle events that are triggered at the client. When a postback occurs, the page is reloaded, and the events are handled by the system. However, it is worthwhile to know the sequence of these activities. As shown in Figure 3.16, the order of execution is Page_Init, Page_Load, Change events, Action events, and finally the Page_Unload event. The Page_Init does not completely load all of the controls. In the Page_Load event, the states of the controls are set. Then the system takes care of the change and action events that occurred at the client’s site. These are executed only in case of a postback.

Figure 3.16 Event Execution Sequence

Code-Behind versus In-Page Coding

In our previous example, we have placed a certain amount of VB code inside the .aspx file. We will refer to this practice as In-Page coding (also referred to as inline coding by some programmers). In ASP days, all ASP applications had to be developed using in-page coding because that was the only way to develop an ASP page. (In those days, the ASP developers envied the VB developers, because the VB developers had a nice way to split their codes and visual presentation.)

Often, the intermixed HTML and scripting codes in a large page become cryptic and difficult to read and maintain. Fortunately, ASP.NET provides a way out of this problem. We may develop the html code in a file with an .aspx extension, and then we may write the necessary code in a separate C# or VB code file. This practice is known as Code-Behind. Basically, the Code-Behind follows the Visual Basic model of developing an application. Here, we develop an .aspx file where we define the layout of the controls in a page, and then we include the code in a separate VB or C# class file. As shown in Figure 3.17, this mechanism separates the page layout design activities from the code development activities. When we develop an ASP.NET application using VS.NET, we are automatically forced to use Code-Behind.

Figure 3.17 In-Page Code versus Code Behind

Obviously, the .aspx file has to be somehow linked to the class file. We may link the .aspx file with the code file in one of two ways:

 Develop the class file and save it without compilation in the same directory of the .aspx file, or

 Compile the class file and save the .dll file in the bin subdirectory of our virtual directory.

It is intuitively assumed that the former will execute more slowly than the latter. Here, we will provide two examples. In both of these cases, we will develop our flower selection page using alternative Code-Behind techniques. First, we will demonstrate an example using VB.NET without compilation and then we will present a code behind example using C# with compilation.

Using Code-Behind without Compilation

The output of this application is shown in Figure 3.18.

Figure 3.18 Run-Time Display of the VB Code-Behind Application

In this method, you do not need to compile the VB or C# source file. Just save the source file and the .aspx file in the same virtual directory. You will need to enter the following Page Declarative statement at the top of your .aspx file. Here, the Src attribute specifies the name of the source file, and the Inherits attribute specifies the name of the class to inherit. In the following illustration, we assume that the VB source file named vbCb.vb has a class named VbCb in a namespace my VbCodeBehind. The complete listing for Figure 3.19 is also available in the CodeBehind.aspx file in the accompanying CD.

Figure 3.19 The .aspx File for the Code-Behind Example (CodeBehindVB.aspx)

<%@ page language=“VB” codebehind=“vbCb.vb” inherits=“myCodeBehind.vbCb” %>

1. Develop the page layout in an .aspx file (shown in Figure 3.19). Be sure to include the page directive.

2. Develop the VB class file (shown in Figure 3.20) and save it in the same directory. In this particular application, we need to import the System and the System.WebUI.WebControls namespaces. Depending on the nature of your applications, you may need to import other namespaces, too. The code for Figure 3.20 is also available in the accompanying CD.

Figure 3.20 The VB Class File for the Code-Behind Example (vbCb.vb)

3. Test the ASPX application. It should work fine.

Using Code Behind with Compilation

In this method, you will need to compile your VB or C# source file to a .dll file first. Then copy the .dll file and save it in the bin subdirectory of your virtual directory. Rather than manually copying the .dll file to the bin directory, you may also use the /out parameter of the compilation command to save the .dll file directly to your bin directory, as follows:

G:\MyAspNets\CodeBehind>vbc /out:‥\bin\vbCb.dll /t:library vbCb.vb

In the compilation command, we assume that the name of the VB file is vbCb.vb. This command will create the vbCb.dll file in the bin directory directly upon compilation. Now we need to enter a page declarative at the top of our ASPX page as follows. Here, the name of the source file (cs or vb) should be specified in the Code-Behind attribute. The Inherits attribute should include the namespace.className of the class file:

<%@ page language=“cs” debug=“true”codebehind=“CSharpCodeBehind.cs” inherits=“myCsCodeBehind.cSharpCb” %>

Although we are staging this example using C#, you may change the VB code shown in the previous example very easily to implement this application in VB. The output of this example would appear exactly similar to the one shown in Figure 3.18.

1. Develop the .aspx file (Figure 3.21). Here, we assume that you will develop the C# class in a file named CsharpCodeBehind.cs. We further assume that the name of the class will be cSharpCb in a namespace myCsCodeBehind. Thus, be sure to include the Code-Behind attribute to link the page to the code behind class file as follows. The code shown in Figure 3.21 is also available in the accompanying CD in a file named CodeBehindCS.aspx.

Figure 3.21 Complete Listing (CodeBehindCS.aspx)

    csc /t:library /r:System.dll /r:System.Web.dll CSharprpCodeBehind.cs

2. Develop the Code-Behind class file as shown in Figure 3.22.The code shown in Figure 3.22 is also available in the accompanying CD in a file named CsharpCodeBehindCS.cs.

Figure 3.22 Complete Listing for CSharpCodeBehind.cs

3. Compile the class file as follows. Note: If you are using the VB version, just replace the csc keyword with vbc, and change the name of the source file.

    cec /t:library /r:System.dll /r:System.Web.dll CSharprpCodeBehind.cs

4. Copy the .dll file in the bin directory of your virtual directory. You are done.

When we develop Web applications using VS.Net, it forces us to implement the code-behind methodology. In the next section we will walk you through the steps for developing a simple application using VS.Net.

Using VS.Net for Developing a Web Application

In this section we will provide a step-by-step procedure to develop a simple Web page using VS.Net. Our finished page will be displayed in the browser as shown in Figure 3.23.

Figure 3.23 The Flower Selection Page Developed Using VS.Net

1. Start a new Visual Basic ASP.NET project as shown in Figure 3.24. Be sure to provide a name for your project.

Figure 3.24 Starting a New VB ASP.NET Web Application

2. After you click OK, the system will display the VS.Net IDE screen. Do not get intimidated by the complex appearance of the screen. With some practice, you will start loving the environment. You will see an empty Web page with two tabs at the bottom: Design and HTML. If the toolbox is not visible, use the View | ToolBox of the system menu to display the toolbox. Click on the Web Forms tab of the toolbox.You will see all of the server controls in the toolbox. Draw a Label. If the Property Window is not visible, use F4 (or View | Property Window menu) to display the property window of the label. Change its Text property to Select a Flower Please as shown in Figure 3.25. Please note that the system is building the WebForm1.aspx file automatically for you.

Figure 3.25 The VS.Net IDE Screen

3. Draw a ListBox control. Change its ID property and Rows property lstFlower and 3, respectively. You may also change its background Color and Font to your taste. Be sure to set its AutoPostBack property to True. Now double-click on any empty place of the form. The system will bring the code screen as shown in Figure 3.26. Please note that the system has already generated the VB Code-Behind. It has named it WebForm1.aspx.vb. In the Page_Load event, enter the necessary code for loading the list box.

Figure 3.26 Code-Behind Screen in VS.Net

4. You are almost done. Go back to the design view of the WebForm1.aspx. Draw a label at the bottom of the list box, and change its ID property to lblMessage. Now double-click the list box. The system will bring the code screen with the template for the lstFlower_SelectedIndexChanged event procedure. Enter the following code in this event:

    lblMessage.Text=“You have selected ” + _ lstFlowers.SelectedItem.Text

Migrating …

ASP Skills Are Not Obsolete

If you are an experienced ASP developer, your skills are not lost. The new ASP.NET programming model will seem very familiar to you. However, most of your existing ASP pages will have to be modified if you want to run them under ASP.NET. The modifications would be quite simple. Some of the VB Script codes would have to be changed to VB.NET code, and the new ADO.NET would replace your ADO-related codes. In most cases, though, the necessary changes will involve only a few lines of code. You may choose to rewrite existing ASP applications to gain the performance, readability, and maintainability improvements of the new development environment. However, because a Web application can contain both ASP and ASP.NET pages, the conversion does not necessarily have to be carried out all at once.

You are done. Go ahead and test it. Before you test it, you may use the Build menu to build your project (compile the code), and then use the Start icon or Debug | Start of the main menu to run the application. Knowingly or unknowingly, you have developed an ASP.NET Web application. The VS.Net has created a virtual directory in your IIS. If you display the Solution Explorer window, you will see that the VS.Net has done a lot of work for you. By the way, if you look at the HTML code in the WebForm1.aspx file, you will see that VS.Net has styled the list box as follows (only selected attributes are shown):

<asp:ListBox id=“lstFlowers” runat=“server” Rows=“3”

BackColor=“#FFE0C0” Font-Bold=“True” AutoPostBack=“True”

Font-Names=“Book Antiqua” Font-Size=“Medium” ForeColor=“#C04000”>

</asp:ListBox>

That means when we develop our .aspx files manually, we can also use these attributes to style our controls.

Using HTML Server Controls

Conventional HTML elements are not programmable at the server side. Their values do not persist in postbacks. These are essentially treated as opaque texts that are passed to the browser. In ASP.NET, we may convert an HTML element to an HTML server control by adding an attribute runat=“server.” This notifies the ASP Engine to create an instance of the control during parsing. We will, of course, need to specify an ID of the element so that we can manipulate it programmatically at the server side. These controls are particularly useful for migrating ASP applications to ASP.NET applications.

HTML server controls have been derived directly or indirectly from the base class System.Web.UI.HtmlControls.HtmlControl and map directly to HTML elements. The hierarchy of HTML server control classes is shown in Figure 3.27. Basically, the hierarchy divides the classes into three major categories: the classes that mimic the HTML <input> tag, the classes that may act as container classes, and finally the HtmlImage class. Several classes in the second category also employ the HTML <input> tag. HTML server controls must reside within a containing <form> control with the runat=“server” attribute.

Figure 3.27 HTML Server Controls Hierarchy

In this section, we will present a number of examples of HTML server controls. If you are relatively new to ASP, be sure to go through these examples. Most of these examples can also be enhanced using the Web controls. Most importantly, the concepts learned in this section will enable you to develop better applications using Web controls.

Using the HtmlAnchor Control

You can use the HtmlAchor control (<a>) to navigate from a page to another page. This basically works almost like the Html anchor tag; the only difference is that it works on the server. It has the following attributes:

If necessary, we can use this control to dynamically modify the attributes and properties of the <a> element and display hyperlinks from a data source. The href attribute contains the URL of the page to be linked to. We have shown an example of anchor controls in Figure 3.28.

Figure 3.28 Embedded HTMLAnchor Controls in an HtmlButton Control

Using the HtmlTable Control

The HtmlTable control mimics the Html <table> tag. We may define rows using <tr> tags. Table cells are defined using <td> tags. This control is a container control, and so we can embed other controls in its cells. It has the following attributes:

In the following example, as you can see in Figure 3.28, we will build an HtmlTable with two rows and two columns. Each cell of the table will contain an HtmlAnchor control.

The code for this application, as shown in Figure 3.29, is self-explanatory. Each pair of <tr> and </tr> entries enable us to define a row, and within each row, we nest a pair of <td> </td> to define the table’s data (cell). In this example, we have embedded an HtmlAnchor control in each cell. The code shown in Figure 3.29 is available in the accompanying CD in a file named HtmlAnchor1.aspx.

Figure 3.29 HtmlAnchor1.aspx

Using HtmlInputText and HtmlTextArea Controls

You can use both of these controls to collect text data from the user. You can use the HtmlInputText control to implement server-side code against the HTML <input type=text> and <input type=password> tags. Its major attributes are these: type (text or password), runat, id, maxlength, size, and value. The HtmlTextArea control enables the user to enter multi-line text. Thus, it is the server-side equivalent to the HTML <textarea> element. Its rows and cols properties can be used to define its size. You can use its onserverchange attribute to run an event handling function.

We will illustrate the usage of these controls with an example. In this application, the user will enter a short story in a text area, and then he or she will enter the name in a textbox, and the password in a password-type textbox. On the click event of a button, we will check the password and display the appropriate message in an html <span> element. The run-time view of the application is shown in Figure 3.30.The code (shown in Figure 3.31) for this application is pretty straightforward and more or less self-explanatory. The code shown in Figure 3.31 is also available in the accompanying CD in a file named HtmlText1.aspx.

Figure 3.30 Using HtmlInputText and HtmlTextArea Controls

Figure 3.31 HtmlText1.aspx

Using HtmlButton and HtmlImage Controls

You will find two of these controls: HtmlInputButton and HtmlButton. The HtmlInputButton supports the HTML Reset and Submit button types. On the other hand, the HtmlButton control can be used to develop server-side code against the HTML <button> element. We can provide custom code for the OnServerClick event. You can customize its appearance and imbed other controls in it. We have used HtmlButton controls in many of our previous examples. In our next example, we will embed an HTML <img> element inside a button. We have used the OnMouseOver and OnMouseOut attributes of a button control to provide rollover effects. We have also shown how to use an in-line style attribute that you can use to format many of the controls. The run-time view of the application and its code listing are shown in Figure 3.32 and Figure 3.33, respectively. The relevant code is also available on the accompanying CD in a file named HtmlButton1.aspx.

Figure 3.32 Using the HtmlImage Control in an HtmlButton Control

Figure 3.33 HtmlButton1.aspx

NOTE

To run this code, you will need to copy the SmallSpinReel1.jpg in the Images folder of your virtual directory.

Using the HtmlInputFile Control

The HtmlInputFile control has been designed to program against the HTML <input type=file> element. We can use this control to enable users to upload binary or text files from a browser to a directory that we specify in our Web server. Its major attributes are as follows:

When this control is rendered, it automatically displays a Browse button for directory browsing. Figure 3.34 illustrates the usage of an HtmlInputFile control. The user may upload a file from his or her machine to our c:\temp directory of the Web server. The code for this application is shown in Figure 3.35 and is available on the CD in a file named HtmlFile1.aspx. As you will observe from this code, we have used the fileControl.PostedFile.SaveAs((“c:\temp\” + targetName.Value)) statement to accomplish the objective.

Figure 3.34 Using the HtmlFile Control for Uploading Files to the Server

Figure 3.35 HtmlFile1.aspx

Using the HtmlSelect Control with Data Binding to a SortedList Structure

The HtmlSelect control has been offered to program against the HTML <select> element. Basically, it enables us to develop a combo box (dropdown list) or a list box. If the size attribute is set to 1, then it behaves like a dropdown list. We may allow the selection of multiple items by using its Multiple property. If we allow multiple selections, we will need to use its Items(i).Selected property to test if its element i has been selected. An HtmlSelect control can be bound to an external data source. Figure 3.36 shows an example of a bound HtmlSelect control.

Figure 3.36 Binding an HtmlSelect Control to a SortedList Object

At first sight, the example will appear to be very simple. However, we have employed a number of common ASP.NET techniques here. Please review the example carefully as it will become very handy when you deal with more challenging applications using Web server controls. Our objective is to bind an HtmlSelect control with a field of a commonly used structure named SortedList. The SortedList structure, like the ArrayList and HashTable, is an offering in the Net SDK Collection Class. We may use a SortedList to store a collection of objects in alphabetic order of a key field. Subsequently, we may retrieve a desired value either by using array-like addressing or by its key. The complete code for this application is shown in Figure 3.37 (and can also be found in the accompanying CD in a file named HtmlSelect1.aspx).

Figure 3.37 HtmlSelect1.aspx

Creating and Loading the SortedList

In the Page_Load event, we have loaded the SortedList as follows:

By default, the name of a flower (the first parameter) will be loaded in the sorted list as the key-field. The price of the flower (the second parameter) will be stored as its value. After the sorted list object is loaded, we have bound the HtmlSelect control to the key-field of the sorted list as follows:

lstFlowers.DataSource=sortedList1.Keys

lstFlowers.DataBind()

On the click event of the button, our intention is to display the price of the selected flower. Where will we get the price?. Obviously, we want to retrieve it from the sorted list object. However, there is a minor problem. Whereas the values of the controls in an ASP.NET page are state-full, the values of the variables are state-less. Hence, on postback, the sorted list would not be available. We may solve this problem in many ways. The easiest way is to load the sorted list again. Placing the relevant code outside the If Not IsPostBack block can do that. But that will cause repetitive loading of the sorted list object on each postback. Therefore, we have instead saved the sorted list in a Session object. Subsequently, we have retrieved the sorted list object from the session variable in the showSelection procedure. The value of the sorted list has been retrieved using its GetValueList method.

Using HtmlCheckBox and HtmlInputRadioButton Controls

We can use the HtmlInputCheckBox control to develop server-side code against the HTML <input type=checkbox> element. This is done using the Checked property of this control. The HtmlInputRadioButton control can be used to provide server-side programmability to an HTML <input type=radio> element. We can group these controls together by specifying a name property common to all <input type=radio> elements within the group. Only one radio button in a group can be checked at a time. Figure 3.38 shows a simple example of these controls. The complete code is shown in Figure 3.39.The code, shown in Figure 3.39, is self-explanatory and can be found in a file named HtmlInputCheck1.aspx in the accompanying CD.

Figure 3.38 Using HtmlCheckBox and HtmlInputRadioButton Controls

Figure 3.39 HtmlInputCheck1.aspx

Developing & Deploying . ..

HTML Server Controls versus Web Controls

At first sight, the parallel existence of these two sets of controls may appear questionable. However, these two types of controls have their advantages and disadvantages. HTML server controls make it easy to convert an existing HTML or ASP page to a Web Form. By converting individual HTML elements to HTML server controls, we can quickly add Web Forms functionality to the page without affecting the rest of the page. Furthermore, if we plan to use a heavy amount of client-side scripts, the HTML server control is the way to go! However, all values in HTML server controls are essentially of string type, and thus there is no type safety.

On the other hand, the Web server controls have a richer and more consistent object model. They automatically generate correct HTML for down-level (HTML 3.2) and up-level (HTML 4.0) browsers. You will need them when you prefer a VB-like programming model, and when you are creating applications with nested controls. However, with server controls we have less direct control over how a server control is rendered in a Response object. We can mix these controls in the same page.

Using ASP.NET Web Controls

The ASP.NET Web controls are also known as Web form controls. Microsoft has included a plethora of Web controls in the System.Web.UI.WebControls namespace. For discussion purposes, we will divide these controls into three major categories:

 Basic Web Controls These Web controls are similar to HTML server controls but have additional features. These controls have a richer and more consistent object model.

 Validation Controls These controls have been developed exclusively for input validation (to be discussed later in this chapter).

 Databound ListControls These belong to the new generation of controls that provide additional power and development speed. These are also typically referred to as Templated Web Controls.

All Web controls are derived from the generic class named WebControl. Thus, the Web controls inherit a common set of class members. Some of the frequently used members include BackColor, BorderColor, BorderStyle BorderWidth, DataBind, Enabled, Font, ForeColor, Height, Page, Parent, Site, TabIndex, ToolTip, Visible, Init, Load, Unload, Dispose, ToString, OnInit, OnLoad, and OnDataBinding.

Basic Web Controls

Table 3.2 briefly describes several server controls that we have classified as basic Web controls. Some of these controls behave similarly. For example, the usages and characteristics of a CheckBoxList control are almost identical to those of a RadioButtonList control. This is why we have grouped these controls under single captions in Table 3.2.

Table 3.2

Basic Server Controls

Many of the basic server controls work very similarly to their HTML server control counterparts. All of the Web controls are prefixed with asp: in their tags. For example, the tag for a label Web control is <asp:Label>. Their uses are also mostly intuitive. All of the examples illustrated in the HTML server control section can also be effectively developed using Web controls. In this section we will present a number of additional examples to demonstrate the uses of Web controls.

Using Labels, TextBoxes, RadioButtons, CheckBoxes, and DropDownLists

In this example, we will develop a simple payroll estimation application to demonstrate Labels, TextBoxes, RadioButtons, CheckBoxes and a DropDownList. We will use a button control to submit a user’s given data to the server. We will collect data on hours worked, and hourly rate using two textboxes. Insurance-related data will be collected using two radio buttons: “No Insurance ($0.00),” and “Family Coverage ($40.00).” We will group these two radio buttons in a group named rgrInsurance. The objective of grouping buttons is to enable the user to select at most one button from the group.

We will provide two check boxes to collect data on company facility use. We will assume that there are two facilities: Parking ($15.00) and Swimming Pool ($10.00). The user should be able to check both items. Finally, we will provide a DropDownList box to collect data on employee status. There will be two types of employees: White-Collar and Workhorse. A white-collar worker will receive a bonus of $100, whereas the bonus for a workhorse is assumed to be $65.88. The run-time view of the application is shown in Figure 3.40. The code for the application is pretty much straightforward. We have shown the code in Figure 3.41. The code is also available in a file named BasicServerControls1.aspx in the accompanying CD.

Figure 3.40 Using Label, TextBox, RadioButton, CheckBox, and DropDownList Web Controls

Figure 3.41 Complete Code for BasicServerControls1.aspx

Using the ListControl Abstract Class

A number of basic Web controls have been derived from the ListControl abstract class. These are CheckBoxList, DropDownList, ListBox, and RadioButtonList. Their usages and characteristics follow a common pattern. If warranted, each of these can be used as a container control. For example, a CheckBoxList control can contain a collection of CheckBoxes. We can set their AutoPostBack properties to true to trigger postbacks on their SelectedIndexChanged events. Each of them has a property named Item. Count that contains the number of items in the collection. The Items(i).Selected property can be used to check if the user has selected an item in the list. Finally, the Items(i).Text property enables us to extract the text of the selected item.

To demonstrate the identical behavior of the controls in the ListControl family, we will develop a simple example. We will load a ListBox control with certain flower names, a RadioButtonList control with some state names, and a CheckBoxList control with some facility names. Just for demonstration purposes, we will set the AutoPostBack properties of all of these controls to true. On click of each of these controls, we will display the user’s selections. We will enable the user to select multiple entries from our list box. Of course, by default, the CheckBoxList control will enable the user to select more than one entry. The complete application, when displayed in IE, will appear as shown in Figure 3.42.

Figure 3.42 Displaying and Manipulating Various List Controls

We have developed this application using VS.Net. The design time view of the form is shown in Figure 3.43. As you can observe from this figure, we have applied a certain amount of styling in the controls.

Figure 3.43 Design Time View of the ListControl Demonstration in VS.Net

The VS.Net created a virtual directory and generated a Web application for this work. It has also generated two major files: WebForm1.aspx and WebFrom1.aspx.vb (the code-behind). It has compiled the WebForm1.aspx.vb to a .dll file and has saved it in the bin directory automatically. The entire application is available in the Chapter3\TestingWebControls directory of the accompanying CD. To test the application, you will need to copy the TestingWebControls directory to your Inetpub\wwwroot directory. Then use the following URL to display the page in your browser: http://localhost/TestingWebControls/WebForm1.aspx.

We will not reproduce the entire code here. In short, we have created three list controls. The RepeatDirection attribute of the CheckBoxList control has been set to “Horizontal” to align the check boxes horizontally. A truncated version of the WebForm1.aspx file as generated by VS.Net is shown in Figure 3.44.

Figure 3.44 Truncated Code Listing for WebForm1.aspx File: VS.NET (TestWebControls directory)

In the WebForm1.aspx.vb code-behind file, we have loaded all of the ListControls in the Page_Load event. In the appropriate events of these controls, we included the instructions to display the selections in respective labels. The user may select more than one entry in the CheckBoxList. Hence, we used a loop to iterate through each of the items. If the item was selected, we included its text in the output. Identical procedures were used to display the selected values in the list box. A truncated version of the relevant code for WebForm1.aspx.vb file is shown in Figure 3.45.

Figure 3.45 Partial Listing of WebForm1.aspx.vb

Using HyperLink Controls

The HyperLink server control enables us to link to a different page. Its Text property is displayed on the screen as a hyperlink. On click of the hyperlink, it links to a page specified in its NavigateUrl property. The displayed text can be replaced by an image by specifying the ImageUrl property. In our next example, we will develop a page with two HyperLink controls. One of them will display text, and the other will display an image. We will specify the “http://ahmed2/Chapter3/ServerControl4.aspx” in both of their NavigateUrl properties. The completed application will be displayed in IE as shown in Figure 3.46. When the user clicks any of the controls, the system will display the specified page. The complete code for the application is shown in Figure 3.47 and is also available in a file named HyperLink1.aspx in the accompanying CD.

Figure 3.46 Illustration of the HyperLink Server Control

Figure 3.47 Complete Listing for HyperLinkl.aspx

Binding a ListControl to an ArrayList

In most of our previous examples, we loaded a list box via code in the Page_Load event. In this section, we will introduce an important concept of a typical ASP.NET development practice. Rather than populating a specific control via code, we may bind a control to a data source (something that contains data). In this case, the control will automatically assume the value or values contained in the data source. At this stage, you may not see the benefit of this approach, but it will shine like a jewel when we learn how to display and manipulate data from databases. In the example shown in Figure 3.36 and Figure 3.37, we have shown a similar example of binding an HtmlSelect control to a SortedList). Since the ArrayList object is also very common in ASP.NET framework, we will bind our ListControl to an ArrayList in our next example.

Often we create and load a collection of objects into certain structures. These structures are known as collection objects. For example, an ArrayList is a collection object. It is actually very similar to a dynamic array of objects. Suppose that one of these ArrayList objects contains the names of some flowers. If needed, we may bind one or more controls to this ArrayList. That way, the controls will be automatically loaded with the values in the ArrayList. Don’t worry! We will not deprive you of binding controls to databases. Those examples will appear later in this chapter.

Binding a control to a data source is very simple. Rather than developing a data loading procedure, we just set the DataSource property of a control to a data source. Then we employ the DataBind() method of the control to accomplish the binding task. In our example, we will first create an ArrayList of flowers, and then we will bind a list box (lstFlower) with the ArrayList. Figure 3.48 shows the runtime view of the application. The complete listing of the code is shown in Figure 3.49 (also available in the accompanying CD in a file named DataBind1.aspx).

Figure 3.48 Binding a ListControl to an ArrayList

Figure 3.49 Complete Listing of DataBind1.aspx

Validation Controls

A validation control enables us to validate an input and display an error message if necessary. It is very much like other server-side controls with certain additional methods and properties. First, the server treats it as an invisible control. After the user has entered erroneous data, it becomes visible. It is a powerful, rapid application development feature; however, a developer needs to understand its behavior and the methods thoroughly before he or she can appreciate it. There are certain rough edges in the Beta 2 version, which hopefully will be polished in the final product. The best strategy to learn the family of controls is to learn them one at a time, and finally to apply the summary validation.

Various types of validation controls are as follows:

 RequiredFieldValidator Checks if the input control has any value.

 RegularExpressionValidator Checks the value against a regular expression (pattern).

 CompareValidator Checks if the value is acceptable compared to a given value or compared to the content of another control.

 RangeValidator Checks if the input control’s value is within a specified range.

 CustomValidator Allows you to develop custom validation.

 ValidationSummary Reports a summary of all errors.

By default, each of the validation controls performs the validation task at the client-side as well as at the server-side. Except for the RequiredFieldValidator, all other validation controls treat an empty field as a valid field. Therefore, we will need to apply a RequiredFieldValidator to every input field that we want to validate. You can attach more than one validation control to an input. For example, we may use a RequiredFieldValidator and a RangeValidator to ensure that an input is not empty and falls within a specified range.

There are a number of common properties in these controls. The major ones are:

 ErrorMessage In case of an error, the system displays this message at the location of the control, and in the summary report, if any.

 Display A validation control is kept invisible until a bad input is entered. In case of a bad input, the system has to display the error message. The display mechanism can be handled in one of three ways.

 Display= “static” Initially, enough room in the page is reserved for the expected error message.

 Display= “dynamic” No room is initially reserved. In case of an error, the message is displayed by displacing existing contents of the page.

 Display=“none” The message won’t be displayed at the location of the control; however, it will be reported in the summary report, if any.

The RequiredFieldValidator Control

In the following example, the user is expected to enter two values. If he or she skips any one of the values and clicks the Submit button, the system will report the error. Please notice that we do not require any extra code for performing this validation. When the Submit button is clicked, the form will be sent to the server, and the server will do the automatic validation. The run-time view of this application is shown in Figure 3.50. The code for this application, as shown in Figure 3.51, is self-explanatory and is also available in the accompanying CD in a file named Validator1.aspx.

Figure 3.50 Using the RequiredFieldValidator Control

Figure 3.51 Validator1.aspx

The RegularExpressionValidator Control

The RegularExpressionValidator control is typically used to match an input pattern. As an example, let us assume that the value of hours-worked field must have one to three digits. In this case, we will add a RegularExpressionValidator to the txtH control. In the RegularExpression property of the RegularExpressionValidator, we will specify a pattern /d{1,3}. This will force the system to raise an error if the user input is not one-to-three digits long. The output of this application is shown in Figure 3.52. The code for this example is shown in Figure 3.53 and is also available on the accompanying CD in a file named Validator2.aspx.

Figure 3.52 Using RegularExpressionValidator Controls

Figure 3.53 Validator2.aspx

NOTE

The details of regular expressions can be found in any Perl book. You may also review http://msdn.microsoft.com/scripting/default.htm?/scripting/JScript/doc/jsobjregexpression.htm.

We have found the following source to be adequate: www.microsoft.com/mind/defaulttop.asp?page=/mind/1098/jscript/jscript.htm&nav=/mind/1098/inthisissuecolumns1098.htm.

The CompareValidator Control

The CompareValidator control compares an input to a specified value or to the value of another control. You can also use it to check if the input is of any particular data type. In our next example, we will add a textbox named txtR. In this textbox, the user will enter the hourly rate. Suppose that we want the data-type of this field to be Double. We will apply a CompareValidator control to test the data-type of the txtR. Note that if the data entered is convertible to the desired data-type, the validation will succeed. The run-time view of the application is shown in Figure 3.54.

Figure 3.54 Using the CompareValidator Control

We have added the code following code to accomplish this objective (you may review the complete code in the file named Validator3.aspx on the CD). Please notice that we have set the type property to “Double,” and the operator property to “DataTypeCheck.”

In the type property of the CompareValidator, we may specify: String, Integer, Double, DateTime, and Currency. In the operator property, we may specify: Equal, NotEqual, GreaterThan, LessThan, GreaterThanEqual, LessThanEqual, and DataTypeCheck.

The RangeValidator Control

You can use this control to check if an input is within an acceptable range. Suppose that we want to provide a textbox for collecting data on “number of dependents.” We want to enforce a constraint that this field should be from 0 to 10. Figure 3.55 illustrates the use of a RangeValidator in this particular situation.

Figure 3.55 Using the RangeValidator Control

In our code, we have used the type, minimumValue, and maximumValue properties of a RangeValidator to apply the constraint. We have applied the RangeValidator as follows: (The complete code is available in Validator4.aspx.)

The CustomValidator Control

In many situations, we may not be able to use the existing validators to validate a complex rule. In that case, we may apply a CustomValidator. When applying a CustomValidator, we may provide our own functions that will return true or false. We may develop the code for server-side validation only, or we may develop the code for server-side as well as the client-side validation. Suppose that the user will enter the data about his or her department number. Also suppose that the department number must be evenly divisible by 10. We will develop a simple custom validator to enforce this rule at the server-side. The run-time display of this application is shown in Figure 3.56.

Figure 3.56 Using the CustomValidator Control

We have developed a VB function named validateDeptNum to perform the check. We have also specified its name in the onServerValidate property of the CustomValidator control. An excerpt from the complete code for this application is shown in Figure 3.57. The complete code is available on the CD in the file named Validator5.aspx.

Figure 3.57 The Code for CustomValidator (Validator5.aspx)

Although this example illustrates the server-side validation, ASP.NET automatically writes client-side code to perform the validation. There are various options available to prevent this from occurring and also not to display the code that shows the client-side JavaScript validation. We will not be going into these in detail. In the server-side custom validation, the validation function is included in the server-side script tag <script language=“VB”runat=“server”>. We need to specify the name of the validation function in the OnServerValidate property of the CustomValidator control. The validator control calls this function with two parameters: the first parameter is the control itself, whereas the second parameter is an instance of the ServerValidateEventArgs class. This object encapsulates the methods and properties that enable us to access the value of the control being validated and to return whether the control has been validated or not.

NOTE

If the client-side validation is active (which is the default), the browser does not submit the form back to the server until all corrections have been made on the client-side. If you have a “server-side-only” custom validator along with some other fields that employ client-side validation, then on click of the submit button, the form may not appear to work properly. That is expected because the browser will not submit the form until all client-side validated fields are correct.

CustomValidator with Explicit Client-Side Validation Function

In the CustomValidator, we may specify a twin client-side validation function. To employ the client-side validation, we will have to specify the name of the client-side validation function in the ClientValidationFunction property of the CustomValidator control. The client-side function needs to be coded in JavaScript, and it should also return true or false. Obviously, the client-side validation should perform the same checks that are done by the server-side validation function.

We will revise our previous example to include a client-side validation function. We have already developed the server-side validation function for the department number textbox. Now we will implement the client-side validation. The run-time display of the application is shown in Figure 3.58.

Figure 3.58 Using CustomValidator with Explicit Client-Side Validation

The part of the code that is pertinent to our example is shown in Figure 3.59. In this code, you will notice that we have specified the name of the JavaScript validation function in the ClientValidationFunction property of the control to be validated. The complete code is available in Validator6.aspx in the CD.

Figure 3.59 Partial Listing of Validator6.aspx

Displaying the Error Message with Style

In this example, we will set various properties of the validation controls to display its message with style. The output of the application is shown in Figure 3.60. We have set a number of properties, such as forecolor, bordercolor, tooltip, and so on, to our number of dependent validators.

Figure 3.60 Displaying Error Message with Style

The part of the code that is relevant to format the validator is shown in Figure 3.61. The complete code is available in the file named Validator7.aspx on the CD.

Figure 3.61 Validator7.aspx

The ValidationSummary Control

The ValidationSummary control enables us to display all errors in a given location. It displays the “errorMessage” properties of respective controls in the summary report. Since the error messages are displayed in the summary, often we suppress the detailed error message in the individual ValidatorControls by placing an asterisk (*) or a short message right after the validator control’s start-tag. Major properties of the ValidationSummary control are the following:

 headerText This is simply a header.

 displayMode Displays the errors in one of the following ways:

 List

 BulletList (default)

 Singleparagraph

 ShowSummary: (True or False) This property can be used to display or hide the summary report programmatically.

Figure 3.62 illustrates the use of a ValidationSummary control. In our example, we have defined the ValidationSummary control as follows.

Figure 3.62 Using the ValidationSummary Control

<asp:ValidationSummary id=“valSummary” runat=“server”

headerText=“Please correct the following errors”

display=“static” showSummary= “True” />

The complete code for the application is shown in Figure 3.63 and is available in the file named Validator8.aspx on the CD.

Figure 3.63 The Complete Code for the Application (Validator8.aspx)

Validating Patterned Strings, Passwords, and Dates

Suppose that we want the user to enter the phone number, date of birth, hire-date, password, and confirmation of password. Also suppose that the business environment dictates that we enforce the following constraints:

 The phone number must follow a pattern like (ddd)ddd-dddd for employees in the USA. It should match dd.dd.dd.dd for employees in France.

 The date of birth must be between 1/1/1940 and 1/12/1985.

 Hire date must be after the date of birth and before 6/15/2001.

 The user should enter the password twice, and both entries must be identical.

We have developed an application to enforce these business rules. The output of the application is shown in Figure 3.64.

Figure 3.64 Validating Patterned Strings and Passwords

The complete code for this application is shown in Figure 3.65 and is available on the CD in the file named Validator9.aspx.We have enforced the underlying constraints as follows:

Constraint 1. We will use a regular expression to implement this constraint. The following regular expressions are identical. Both of these expressions will test the pattern (ddd)ddd-ddd:

ValidationExpression=“\(\d\d\d\)\d\d\d\-\d\d\d\d“> ValidationExpression=“\(\d{3}\)\d{3}\-\d{4}”

ValidationExpression=“\d{2}\.\d{2}\.\d{2}\.\d{4}”

However, for French employees we must also test a pattern like dd.dd.dd.dd. The regular expression for this pattern would be this:

ValidationExpression=“\d{2}\.\d{2}\.\d{2}\.\d{4}”

We may parenthesize these two expressions and connect them with a pipe (|) symbol to specify that any one of the expressions needs to be satisfied, as follows:

ValidationExpression=“(\(\d{3}\)\d{3}\\d{4})| (\d{2}\.\d{2}\.\d{2}\.\d{2})”

Constraint 2. We have used a RangeValidator to enforce this rule.

Constraint 3. We have used a combination of the CompareValidator and the RangeValidator. The CompareValidator checks whether the date in txtDateHired is greater than that in txtDateOfBirth. The code for that is as follows:

The RangeValidator checks whether the date in txtDateHired is less than “6/15/2001.” The minimumValue is set to “1/1/1900” because the RangeValidator will not work unless both the minimumValue and maximumValue are both present. The code snippet follows:

Figure 3.65 Validator9.aspx

</form></body></html> The Databound ListControls Family

In this section, we will discuss the Databound ListControls. This family of controls is new to ASP developers. These controls provide rapid application development to display and manipulate data from any data source. The following controls shown in Table 3.3 belong to this family.

Table 3.3

The Databound ListControls Family

In earlier sections of this chapter, we illustrated data binding examples on HtmlSelectControl (Figure 3.36), and asp:ListBox control (Figure 3.48).We may use similar techniques to bind data to a CheckBoxList, DropDownList, or a RadioButtonList control. In this section, we will instead introduce three of the most prominent members of this family: Repeater, DataList, and DataGrid.

In our demonstrations, we will use a sample database named Products.mdb, which you can find on the CD accompanying this book. It is a Microsoft Access 2000 database. It contains only one table, named Products. Figure 3.66 shows some sample records in this table. Basically, the table has four columns: ProductId (AutoNumbered Long Integer), ProductName (Text 50), ImagePath (Text 150) and Price (Currency).The ImagePath column contains the name and location of an image relative to a virtual directory.

Figure 3.66 Sample Records in the Products Table

You will learn database connectivity issues in Chapter 7.When we connect to a database, we typically run a query and populate a data table of a data set with the results of the query. In this chapter, we will not discuss the mechanics of how to connect to a database. To understand the remainder of this chapter, it will be sufficient to know that we can bind a ListControl to a data table of a data set. In most of the examples, we will use a subprocedure to populate a DataSet named myDataSet. The listing of a similar subprocedure is shown in Figure 3.67. Temporarily, we will treat this code as a black box (until you have read Chapter 7).This code will populate a data set and subsequently bind a specific ListControl to the data set.

Figure 3.67 Populating myDataSet and Binding a ListControl

NOTE

To try the examples in the remainder of this chapter, you will need to do the following:

1. Copy the Products.mdb in your hard drive. In each sample program, locate the bindListControl subprocedure (shown in Figure 3.67), and adjust its line number 7 to specify your drive. For example, if you have loaded Products.mdb in your C drive, then change line number 7 of the bindListControl procedure to Data Source=C:\Products.mdb.

2. Copy the image files from Chapter3/Images directory of the CD and paste them in the Images subdirectory of your virtual directory.

Actually, the preceding code is not difficult to understand. First we have defined the necessary object variables to connect to a database. In lines 6 and 7, we have provided the information about the driver to be used, and the location of the database. A SQL statement is constructed in lines 8 and 9.We have instantiated the connection object in line 10, and opened the connection in line 11. An OleDbDataAdapter object was instantiated using the SQL string and connection string. The dtProducts data table of the myDataSet data set is populated in line 14. Then we set the DataSource property of a repeater control to the dtProducts. Finally, in line 15, we have bound the repeater to its data source. We will be using similar logic in each of our ListControl examples with minor variations in the SQL statement.

Using the Repeater Server Control

The Repeater is essentially a template-driven data-bound list. The Repeater control allows fragments of html tags inside the templates. For example, we may start a <table> in the Header template and end the table (</table>) in the Footer template, if necessary. The control binds its Item collection to the its DataSource. We may use the Item Command event to process events that are raised from the templates of the control.

We may specify the following templates for a Repeater control:

 Item Template Specifies the DataItem fields to be displayed, and the layout (required).

 AlternatingItemTemplate Defines the layout of the zero-based odd indexed items (optional).

 SeparatorTemplate In this template, we can specify the separator such as <hr> or <br> between repeating items (optional).

 HeaderTemplate Specifies the header of the list (optional).

 FooterTemplate Specifies the footer of the list (optional).

We will provide two examples to illustrate the behavior of a repeater control. In the first example, we will display our product information using a repeater control. In the second example, we will illustrate how to capture an event from a control residing inside a repeater control (known as Event bubbling).

Displaying Data in a Repeater Control: Suppose that we want to display our products data for the products that cost more than $45.00. The expected display for this application is shown in Figure 3.68.The code for this application is shown in Figure 3.69 and is also available in the accompanying CD in a file named Repeater1.aspx.

Figure 3.68 Displaying Data in a Repeater Control

Figure 3.69 Repeater1.aspx

In this application we have defined three templates for our repeater. The Header template starts an HTML table with a <table> tag. The Footer template completes the table with a </table> tag. The ItemTemplate contains the table cells to house the data values. We will extract data from the Products table from the Products.mdb database. First we will populate a data set object, and then we will bind the repeater to this data set. Detailed code for populating the data set and binding the repeater is shown in Figure 3.69.

Once a data table has been populated, only two statements are required to bind a repeater. We need to set its DataSource property to the appropriate data table, and then we can apply its DataBind() method to accomplish the job. These two statements are as follows:

repeater1.DataSource=myDataSet.Tables(“dtProducts”).DefaultView

repeater1.DataBind()

We know that the dtProducts table of our data set will contain columns like ProductId, ProductName, etc. Our objective is to develop an ItemTemplate where we want to specify which column should be shown in what format. For each row of the table in the data set, the repeater will employ this template to display the data. A typical way to display a desired field is to use the <%# Container .DataItem(“columnName”)%> syntax. For example, the following ItemTemplate will display the ProductId in a cell of a table (assuming that the <table> tag has been specified in the HeaderTemplate):

<ItemTemplate>

<tr><td><%# Container.DataItem(“ProductId”) %>

</td></tr>

</ItemTemplate>

Similarly, as shown in the following statement, an Img control can also be specified to render an image:

Img src=‘<%# Container.DataItem(“ImagePath”) %>‘

Using Event Bubbling and Capturing Events in a Repeater Control: You can use the Repeatercontrol to accomplish much more than just displaying data. In its templates, we may insert other controls. In this example, we will place an asp:Button control in the ItemTemplate of our repeater. As shown in Figure 3.70, the repeater will display a button for every record in its data source. We may capture the click event of this button and perform appropriate processing. In this example, we will just display the selected ProductId. Would it not be an excellent way to enable the users to select items in a shopping cart application?. On each selection, we could have written the selected data in a database.

Figure 3.70 Event Bubbling in a Repeater Control

The complete code for this application is shown in Figure 3.71 (and is also available in a file named Repeater2.aspx, in the accompanying CD). A repeater is essentially a container control. When we defined the repeater, we set its OnItemSelection attribute to a function named “showSelection” as follows:

Figure 3.71 Repeater2.aspx

<asp:Repeater id=repeater1 OnItemCommand=“showSelection” runat=“server”>

Whenever a child control in a repeater raises an event, it will report it to its parent, the repeater. The repeater will fire the showSelection function. This phenomenon of a child reporting an event to its parent is known as Event Bubbling. A Repeater (or any such parent) may receive events from many embedded child controls; hence, it may not clearly identify which of the children raised the event. Therefore, the child needs to pass certain information about itself when reporting an event. This is accomplished by the second parameter of the event procedure. The second parameter is defined as e As RepeaterCommandEventArgs. Naturally, the parameter e will be of a RepeaterCommandEventArgs object type (data type), and its CommandSource will identify the child raising the event. Similar event bubbling is employed in many cases where a parent control contains child controls. That is how, as shown in the following code excerpt, we are displaying the value of the ProductId in our message:

Sub showSelection(s As Object, e As RepeaterCommandEventArgs)

lblMessage.Text=“You have selected ProductID : ” _

End Sub

But, wait a minute! How did we get the ProductId value displayed on a button anyway?. Well, that is actually very easy. As shown in the following code excerpt, the button was placed inside the ItemTemplate, and we set its text property to the “<%# Container.DataItem(“ProductId”)%>”.

The remainder of the code is self-explanatory.

Using the DataList Control

The DataList control is similar to the Repeater control. However, it has some additional properties and templates that you can use to display its data in a diverse fashion. The Repeater control does not have any built-in layout or style. We are forced to specify all formatting-related HTML elements and style tags. On the other hand, a DataList control provides more flexibility to display data in a desired layout. It also provides data selection and editing capabilities. How does it do it?. Well, in addition to the five templates that a repeater has, the DataList control has two more templates: SelectedItemTemplate, and EditItemTemplate. These templates are useful for allowing data selection and data editing functionalities. Furthermore, the RepeatDirection and RepeatColumns properties of a DataList control can be exploited to lay out the data in horizontal or vertical fashions.

In this section, we will present two examples. The first example will illustrate the use of the RepeatDirection and RepeatColumns properties. The second example will demonstrate how to enable the user to select a particular data being displayed using a DataList.

Using RepeatDirection and RepeatColumn Properties of a DataList

In this example, our objective is to display the product’s data in a fashion as shown in Figure 3.72. A data table in a data set is essentially a relational databaselike table in the computer’s cache. It has rows (records) and columns (fields) of data extracted from the database. When we bind a ListControl to a data table, each record of the data table becomes an Item in the ItemList collection of the ListControl. In this particular example, we want to display three of these Items in each row of our display (horizontally).This is why we have defined the DataControl as follows:

Figure 3.72 Displaying Data Using RepeatDirection and RepeatColumn Properties

<asp:DataList id=“dataList1” border=0

RepeatDirection=“Horizontal” RepeatColumns=“3” runat=“server”>

The remainder of the code for this application, as shown in Figure 3.73, is straightforward. The code is also available in a file named DataList1.aspx in the accompanying CD.

Figure 3.73 Listing of DataList1.aspx

Capturing Selected Items in a DataList Control: In this example, we will use a DataList control to display the product names in a tabular fashion. Within the DataList control, the product names are displayed using link buttons. The output of this application is shown in Figure 3.74. Once the user selects a particular product name, our objective is to display the name of the selected product. We will also display the index number of the selected item. What index number?. Well, you already know that when a ListControl is bound to a data table, all rows of the table are included as Items in the ItemList collection of the ListControl. The first such Item will have an index value of 0, the second item will have an index value of 1, and so on …! It is the value of that index which we will display.

Figure 3.74 Capturing Selected Items in a DataList Control

The definition of the DataList is itself very simple. We have included the OnItemCommand attribute of the DataList to the showSelection procedure, as follows:

Subsequently, we have embedded a LinkButton control in the ItemTemplate of the DataList. On the click event of this LinkButton, it will send the ProductName as the CommandArgument to the showSelection function. These are accomplished as follows:

In the showSelection procedure, we are simply displaying the desired information as shown in the following code excerpt:

The complete code for this application is shown in Figure 3.75 (and is also available in a file named DataList2.aspx in the accompanying CD).

Figure 3.75 DataList2.aspx

Using the DataGrid Control: The DataGrid Control happens to be the most versatile and powerful member of the data-bound control family. In addition to the functionalities offered by a DataList, the DataGrid control offers sorting and paging capabilities. We can employ its <AllowSorting> property to dynamically sort and re-display data on selection of a column header. In case of very large data source, we can use its <Allow Paging> property to display a selected page of data.

Essentially, a DataGrid control can be used to display bound data in tabular format. Each record in the data source is displayed as a row in the grid. By default, the data grid maps each field of the data source as a column in the grid. Obviously, we may override the default value of its AutoGenerateColumn property to display selected columns in a particular order. In this section, we will present five examples to demonstrate various features of a DataGrid.

Displaying Data in a DataGrid Control Using Default Column Mapping: In this example, we will use the default layout of a data grid to display the bound data. The expected output of this example is shown in Figure 3.76. Exactly like a Repeater, or a DataList control, the DataGrid control also requires binding to an appropriate data source. Besides the binding chore, the specification of the data grid, particularly in this example, is extremely simple as follows:

Figure 3.76 Displaying Data in a DataGrid Control

<asp:DataGrid id=“datGrid1” runat=“server” />

The complete listing of the application is shown in Figure 3.77. The code is also available in the accompanying CD in the file named DataGrid1.aspx.

Figure 3.77 DataGrid1.aspx

Displaying Formatted Data with Styles: In this example, we will illustrate how to format and style the contents of a DataGrid. We will also demonstrate how to lay out the columns in a different order other than the original order of the columns in the data source. The runtime view of the application is shown in Figure 3.78. The complete code is shown in Figure 3.79. Please notice that our SQL statement for the data extraction procedure is “SELECT ProductID, ProductName, Price FROM Products WHERE Price > 40 ORDER BY Price”.That means the data table “dtProducts” will contain three columns exactly in that order. However, the sequence of the columns displayed in the data grid is ProductId, Price and ProductName. Furthermore, we have formatted the Price field. We have also changed the captions in the column headings.

Figure 3.78 Displaying Formatted Data with Styles

Figure 3.79 DataGrid2.aspx

First, we have to set the AutoGenerateColumn property to False to suppress the automatic generation of the columns in the DataGrid. The DataGrid has a <Column> collection property. Inside the <Column> tag, we can include the column names of the desired columns using the <BoundColumn> property. We do not have to necessarily include all of the columns, and we can list the columns in the desired order. The necessary formatting instructions for a column can be specified inside the <BoundColumn> tag. We can also include the <ItemStyle> property of a <BoundColumn> object to specify the alignment of the text. For example, we have formatted the Price column as follows:

<asp:BoundColumn HeaderText=“Unit Price” DataField=“price”

DataFormatString=“{0:c}”>

<ItemStyle HorizontalAlign=“Right”/>

</asp:BoundColumn>

We have used the <HeaderStyle> property to define the look of the header. Finally, the <AlternatingItemStyle> property has been used to display the rows in alternating background colors. The complete code for this application is shown in Figure 3.79 and can be found on the CD that accompanies this book in the file named DataGrid2.aspx.

Sorting DataGrid: Yes, on click of any of the column headers, we can dynamically sort the records of a data grid. However, please bear in mind that the DataGrid itself does not provide the sorting algorithm. It rather provides a mechanism to enable us to call a sorting routine. Fortunately, in our example (as shown in Figure 3.80), we do not need to implement a sorting algorithm ourselves. We have used the SQL ORDER BY clause to automatically sort the retrieved data.

Figure 3.80 Sorting Data in a DataGrid Control

The code for this application is shown in Figure 3.81. The code is also available on the CD that accompanies this book in the file named DataGrid3.aspx. On the click event of a column header, our intention is to exploit the SQL’s ORDER BY clause to perform the sorting. This forces us to recreate the data set and subsequently to rebind the data grid. Please observe that we have designed the bindDataGrid routine slightly differently from the similar procedures in our previous examples. We included an optional parameter to this procedure so that we can pass a column name when we call this routine. This subprocedure will then extract the data from the database in the ascending order of the passed column. In the DataGrid tag, we have specified its AllowSorting property to be true. We have also set its OnSortCommand to a subprocedure named sortGrid. On the click event of any of the column header, the sortGrid subprocedure will be called.

Figure 3.81 DataGrid3.aspx

NOTE

If needed, we may also use the Sort method of a DataView object to sort the columns of the underlying data table. In this case we may use the following types of code:

Dim myDataView As DataView

myDataView=myDataSet.Tables(“dtProducts”).DefaultView

myDataView.Sort=sortField

dataGrid1.dataSource=myDataView

dataGrid1.DataBind()

Providing Paging in DataGrid

In case of a large data table, we may want to provide paging capability to the user. We may implement the paging functionality in many different ways. In this context, we will present two examples. First, we will illustrate how to provide a pair of VCR style icons to enable the user to navigate to the previous or the next page of the data displayed in a data grid. Later, we will present an example that will show how to enable the user to navigate to a particular desired page.

Using Previous Page and Next Page Icons: The run-time view of this application is shown Figure 3.82. To accomplish the paging, we have set the following properties of the data grid:

Figure 3.82 Using VCR Style Icons for Page Navigation

 AllowPaging=“true”

 PageSize=“5”

 PagerStyle-HorizontalAlign=“Center”

 OnPageIndexChanged=“doPaging”

The data grid automatically generates the previous page and next page icons. When any one of these icons is clicked, the do Paging subprocedure is triggered. The click event passes a DataGridPageChangedEventArgs parameter to the subprocedure. In the do Paging procedure we have set the currentPageIndex property of the data grid to the newPageIndex property of this parameter. Then we issued a call to the bindDataGrid procedure as shown in the following code excerpt. The complete code for this application is shown in Figure 3.83 and can be found on the CD that accompanies this book in the file named DataGrid4.aspx.

Figure 3.83 DataGrid4.aspx

Sub doPaging(s As Object, e As DataGridPageChangedEventArgs)

dataGrid1.CurrentPageIndex=e.NewPageIndex

bindDataGrid

End Sub

NOTE

Every time we navigate to a different page, the entire data table is populated again, even we if are viewing only five records. Thus, for a very large data table, the speed of execution will slow down significantly. In that case, an alternative technique would involve keeping track of the page numbers programmatically. That can be accomplished by operating on the underlying data table’s rows in the cache. We may also employ a Parameterized Stored Procedure to alleviate this problem.

Navigating to a Selected Page

In our previous example, we could only move to the previous or next page. We can sure do better than that! We can display a list of page numbers, and the user can click any one of these page numbers to move to the desired page. In this example we will illustrate how to accomplish this objective. The run-time view of the application is shown in Figure 3.84. The code for the application is shown in Figure 3.85 and can be found on the CD that accompanies this book in the file named DataGrid5.aspx.There is actually nothing much new in the code, except that we have set several paging related properties as follows:

Figure 3.84 Paging in a DataGrid Control

Figure 3.85 DataGrid5.aspx

AllowPaging=“true” PageSize=“5” PagerStyle-Mode=“NumericPages”

PagerStyle-HorizontalAlign=“Center” OnPageIndexChanged=“doPaging”

Providing Data Editing Capability in a DataGrid Control

We can enable the user to edit data in a DataGrid or DataList control. Typically, we accomplish this by employing the OnEditCommand, OnCancelCommand, and OnUpdateCommand properties. If needed, we can also use the OnDeleteCommand property of a DataGrid control to allow deletion of a selected record. The OnDeleteCommand property is not available in a DataList. In this example, we will illustrate how to allow data editing capability to the user. The run-time view of the application is shown in Figure 3.86.

Figure 3.86 Editing Data in a DataGrid Control

The code for this application is shown in Figure 3.87. The code is also available in the CD that accompanies this book in the file named DataGrid6.aspx.We have a number of major issues to cover here. First, we have used four additional properties of the DataGrid as shown in the following code excerpt:

Figure 3.87 Editing in DataGrid (DataGrid6.aspx)

DataKeyField=“ProductId” OnEditCommand=“setEditMode”

OnCancelCommand=“cancelEdit” OnUpdateCommand=“updateDataBase”

As you can see from the previous code, we have set the OnEditCommand property to a subprocedure named setEditMode. When we specify such a property, the data grid automatically places a ButtonList control captioned as “Edit” in the first column of the displayed table. On the click of this ButtonList, the control triggers the OnEditCommandEvent and passes a DataGridCommandEventArgs parameter to the wired-up event procedure (in this case, to the setEditMode procedure). In our setEditMode subprocedure, we have simply placed the clicked row in the edit mode as follows:

Sub setEditMode(s As Object, e As DataGridCommandEventArgs)

dataGrid1.EditItemIndex= e.Item.ItemIndex

bindDataGrid

End Sub

When the Edit button is clicked, the data grid also displays the Update and Cancel buttons automatically. Furthermore, the editable columns in the clicked row (item) are replaced with textboxes. The user can enter appropriate data in these textboxes and subsequently click the Update or Cancel button.

Second, on the click event of the Update button, we need to update the database. But how would we know which record in the database to update?. This is why we have used the DataKeyField property (in the DataGrid tag) to identify the ProductId field as the key field. Our primary objective is to prepare an appropriate SQL Update statement like UPDATE Products SET ProductName=‘givenName’, Price=‘givenPrice’ WHERE ProductID=‘selectedProductId’. When the Update procedure is triggered, it is passed with a DataGridCommandEnentArgs-type parameter. We can retrieve the key value of the clicked row as dataGrid1.EditItemIndex= e.Item.ItemIndex.

Getting the value of the key field is not enough. We will also have to know the new values of the other edited columns. The desired values can be retrieved using the DataGridCommandEventArgs, too. For example, the ProductName field happens to be the second cell of the selected row. The Controls(0) of a given Cell of an Item object contains the value. But the parameter was passed to the routine as an object. Thus, we need to cast the Controls(0) to a textbox type, so that we can extract its Text data. The following statement will capture the new data in the ProductName column and will place it in a string varianble. Once we have done all these things, it is just a matter of building the necessary SQL string for the appropriate UPDATE query.

strPName=(CType(e.Item.Cells(2).Controls(0), Textbox)).Text

An UPDATE query is typically executed by using the ExecuteNonQuery method of a Command object (to be learned in the database chapter). This is what we did here. Finally, we need to set the edit-mode off. We have done this with the dataGrid1.EditItemIndex= −1 statement. Obviously, we do not want the user to edit the primary key. Therefore, we have set the ReadOnly property of the ProductID column to True.

Creating Custom ASP Server User Controls

We may develop our own server controls by extending an existing control or a group of controls to provide additional functionalities. As stated earlier, there are two versions of custom controls: Web User Controls and Web Custom Controls. The Web User Controls are easy to develop and these are typically stored as ascx files. The Web Custom Controls require in-depth knowledge of Object Oriented Programming and CLR. These are stored in compiled form as assemblies.

A user control, if developed correctly, functions like any other controls. It can be placed inside any other host ASP page (often called the “Consumer” of a control). In this section we will provide two examples on how to develop and use a Web User Control. In the first example, we will develop a very simple user control. In the second example, we will develop a user control that will expose some of its properties to its host page class.

Creating a Simple Web User Control

Suppose that we want to build the control as shown in Figure 3.88. If a host page embeds this control, it will automatically display the current time in the server’s time zone. Once we build this control, we can use it in any subsequent page. We will provide a step-by-step procedure to build this control.

Figure 3.88 A Sample User Control

1. Develop the necessary code for the control. The code for this example is shown in Figure 3.89 and can be found on the CD that accompanies this book in the file named TimeUserControl.ascx. The code is essentially very simple. We are using use a <table> tag with an embedded <asp:Label> control. In the Page_Load event, we will display the current time in the label.

Figure 3.89 The Code for the User Control (TimeUserControl.ascx)

2. Save the code with an extension of *.ascx in your virtual directory.

3. Test the User Control: A control cannot be tested unless it is hosted in an ASPX page. Thus, start a new page, and enter the code shown in Figure 3.90. The code can be found on the CD that accompanies this book in the file named TestTimeUserCntrol1.aspx. First, a host page needs to register a user control using the Register directive. The Register directive has three major attributes. We provide a prefix in the tagprefix attribute (it can be any prefix of your choice). Then we need to provide a name of the registered control in the tagname attribute. Finally, we must also specify the name of the source code (of the .ascx file) using the Src attribute. Can you believe that you are done?. Go ahead and open the page in your browser. You will see a page very similar to the one shown in Figure 3.91.

Figure 3.90 Testing the User Control (TestTimeUserCntrol1.aspx)

Figure 3.91 Using a User Control

Exposing Properties of a User Control

Obviously, the control developed in our previous example does not do much more than display the current time. If judiciously designed, a user control can actually play an extremely crucial role in systems development practice. We can develop user controls to encapsulate standard business processes. A user control is essentially a visual component (almost like ActiveX controls and visual JavaBeans), except that it is much easier to develop. Once we develop the component, it can be plugged in many applications, thereby making it easy for the front-end application developers. More importantly, it provides the mechanism to implement standard business processes and maintain their integrity.

We will illustrate this concept with an example. In this example, we will encapsulate a simple business rule for computing gross wage. The interesting feature of this control is that it will pass the result of its computation to the host page for further processing. It will also accept a title from the host page and display it within itself. That means we will provide two-way communication between the control and the host page. The run-time view of the control when hosted in a page is shown in Figure 3.92.

Figure 3.92 Exposing Properties of a User Control

Developing the Payroll User Control

The code for this user control is shown in Figure 3.93 and can be found on the CD that accompanies this book in the file named UserControlPayroll.ascx. As can be observed in the listing, we have provided number of labels, two textboxes, and a button in this user control. These are named lblTitle, txtH, txtR, and cmdCompute. In the script, we have provided two properties: Title and grossWage. The grossWage property is defined as ReadOnly, so the host page will not be able to change its value. The Title property simply returns the content of the lblTitle. However, the host page will be able to set its value during the run-time.

Figure 3.93 UserControlPayroll.ascx

Consuming the Payroll User Control

We have tested the previous user custom control in a page named UserControlPayrollTest.aspx. The code for this page is shown in Figure 3.94, and can be found on the CD that accompanies this book in the file named UserControlPayrollTest.aspx. First, we have registered the user control with a tagprefix of userCtrlPayroll and a tagname of payroll. We inserted one of these controls in our page using the runat=“server” attribute. This will ensure that the controls in the user control persist during postbacks. We have set the Title property of the control to “The University of Toledo” as follows:

Figure 3.94 Consuming the Payroll User Control (UserControllPayrollTest.aspx)

<usrCtrlPayroll:payroll id=“usrPayCtrl” runat=“server”

Title=“University of Toledo”/><br>

After the user enters the data in the user control, he or she will click the Compute Pay button inside the user control. The user control will apply its own business logic (comptePay procedure) to compute the gross wage. As a consumer of the user control, we do not need to know the details of how the gross wage is being computed. However, we need its value to compute appropriate tax in our own application (page). Fortunately, the user control has exposed the value of the gross wage as a property. Thus, we have developed the following code to compute the value of tax:

Sub computeTax (s As Object, e As EventArgs)

Dim t, gWage As Single

gWage=usrPayCtrl.grossWage()

t=gWage * 0.10

--- ---

End Sub

In this example, we have demonstrated how to develop a user control and expose its properties. We have maintained the states of the properties of the user control. This was accomplished by exploiting the controls embedded in the custom control and by using the runat=“server” attribute. In an advanced custom control, we may avoid this trait by maintaining the states of the variables using objects similar to the old ActiveX Controls “PropertyBags”. However, that topic is not within the bounds of this chapter.

Summary

This chapter has been about ASP.NET Web Controls. The ASP.NET controls are placed in Web pages. Thus, we cannot isolate them and discuss them without knowing how the ASP.NET Engine works, and how it maintains the states of the server controls. Hence, we presented brief overviews of various concepts like HTML Forms, server-side processing, and in-page coding vs. code-behind. We have also given a step-wise procedure to develop a simple ASP.NET project using VS.NET.

We have essentially covered almost all of the HTML server and Web server controls in this chapter. We have also introduced you to a very promising technology named Custom User Control. We have not presented two special purpose controls, namely the Calendar and the AdRotator controls in this chapter. Detail examples of these controls are available in plenty of sources (including the SDK documentations). After you practice the examples presented in this chapter, you will not have much difficulties in tackling these two controls.

The ASP.NET server controls are here to stay. They provide exceptional functionalities and abilities to develop server-side codes just like the VB 6 codes we used to develop in the old days. The bound controls make it easy for us to develop powerful data-oriented applications on the Web very fast. We have illustrated many of these controls with simple examples. However, each of these controls has many properties and events beyond the materials presented in this chapter. A complete book can be written on data-bound list controls, and still the richness of these controls would not be covered in full. The details of the beauties and the beasts behind these controls are anxiously waiting for you in the SDK documentation. After you complete this chapter, be sure to go and grab them from the SDK documentation! Pretty soon, you will be one of the most successful ASP.NET developers.

Solutions Fast Track

Major Features of ASP.NET Server Controls

 There are four types of ASP.NET server controls: HTML Server Controls, Web Server Controls, Validation Controls, and Custom Controls. HTML server controls can be used to run server-side code against conventional HTML controls. The Web server controls follow standard object-oriented programming model and provide rich functionalities. Custom controls enable users to develop their own controls. The Validation controls allow data validation.

 HTML uses HTTP protocol. HTTP is state-less.

 The client can submit data to the server using the GET or POST method. The GET method transmits the data by augmenting the data in the URL. The POST method packages the data inside the BODY of a HTTP massage.

Server-Side Processing in ASP.NET

 When a server receives a request for a page, it retrieves the page from the disk and gives it to the ASP Engine. The ASP Engine compiles the page and creates a page class. Subsequently, the class is instantiated and executed, thereby providing a Response object. The server sends this Response object back to the client.

 ASP.NET server controls are state-full. The system maintains the states of the controls automatically. All server controls are typically defined with a runat=“server” attribute.

 When a user enters data and submits a form back to the server, it is known as PostBack. On a PostBack, the server reloads the form, and the events generated at the client-side are handled at the server. In conventional HTML, typically a Submit button is used to submit data from the client to the server. However, many Web server controls can also trigger PostBacks.

 When a page is loaded and executed, the sequence of events are: Page_Init, Page_Load, Change events, Action events, and finally the Page_Unload.

Code-Behind versus In-Page Coding

 In an ASP page, scripts and HTML tags are usually intermixed. This is known as In-Page Coding.ASP.NET pages can be developed using this procedure. However, ASP.NET provides an alternative methodology to develop a page. It enables separation of HTML tags (presentation) from the processing logic (code).This is known as Code-Behind. It is essentially very similar to the VB development model.

 VS.NET follows Code-Behind methodology for ASP.NET development.

Using HTML Server Controls

 HTML controls are not programmable at the server-side. Their values do not persist. The HTML server controls have been developed both of these problems. The ASP Engine maps the HTML server controls to HTML controls before a page is sent to the client.

 Certain HTML server controls can be bound to a data source. For example, if a list box is bound to a data source, it is automatically loaded with the data in the data source. This is known as data binding.

 If necessary, we can mix HTML server controls and Web server controls in the same page.

Using ASP.NET Web Controls

 These controls are similar to the HTML server controls; however, these controls have a richer and more consistent object model.

 Some of the new and powerful Web controls are: Repeater, DataList, and DataGrid. These are also known as Data-Bound Templated control. These controls allow displaying data from a data source almost automatically. The DataGrid and DataList controls allow data selection and data editing.

 A validation control enables us to validate an input and display an error message if necessary.

 There are six Validation Controls: RequiredFieldValidator, RangeValidator, CompareValidator, RegularExpressionValidator, CustomValidator, and ValidationSummary.

 The Validation controls automatically generates client-side and serverside validation code. If necessary, you can also develop custom validation functions.

Creating Custom ASP Server User Controls

 Custom controls are similar to ActiveX controls, except that these are much easier to develop.

 There are two types of custom controls: Web User Controls and Web Custom Controls.

 A custom control can be used exactly like any other Web server controls.

Frequently Asked Questions

The following Frequently Asked Questions, answered by the authors of this book, are designed to both measure your understanding of the concepts presented in this chapter and to assist you with real-life implementation of these concepts. To have your questions about this chapter answered by the author, browse to www.syngress.com/solutions and click on the “Ask the Author” form.

Q: How much will ASP syntax change during the transition from Beta 2 to the final version?

A: Microsoft has “predicted” that there will be no syntactical changes. This should be good news to developers who were faced with some confusion when certain classes were dropped, added, and modified during the last transition from Beta 1 to Beta 2.

Q: What happens to the existing ASP applications when the .Net Beta 2 SDK is installed and .aspx files enter the picture?

A: Nothing! The good news is that files extensions used by ASP (.asp, .asa, etc.) are completely separate from the ones used by ASP.NET (.aspx, .asax, .ascx, etc.) and do not override each other even in the same directory. The bad news is that settings made in the global.asa file are not accessible to those made in the global.asax file, and therefore you have to redo some setting to get some consistency.

Q: Are paths such as HREFs in user controls relative to the user control or to the host page that they are in?

A: The paths are relative to the user control and not to the host page. This makes it much easier for the user control to find things irrespective of what directory the calling .aspx file is. Another interesting feature in paths is that you can use the “∼” to represent the application root to shortcut the use of the Request Application path. This really makes the building of large Web sites more manageable.