Simple Before Complex

Some common words of wisdom are that you must first learn to crawl before you learn to walk. Nowhere do these words ring more true than in the case of web application development. When building complex functionality, it is often better to start with a simple foundation and gradually build upon it. This technique can be used both when you are building new functionality and when you are debugging existing functionality that doesn’t seem to be working properly. It is much easier to find the source of a problem when you are building in small steps rather than in large ones. Take the following scenario as an example. Imagine that you want to build a form that has a text field that must contain a value when the form is submitted.You want the form to be validated by a dynamically generated ASP.NET RequiredFieldValidator control.

The Basics

The first order of business is to get the form to display. That is done with the ASP.NET code shown in Listing 3.7.

Listing 3.7. Displaying a Simple Form
<%@ Page Language="C#" ClientTarget="DownLevel" %> 

<form id="frm1" runat="server"> 
     <asp:TextBox id="text1" runat="server" /> 
     <br> 
     <asp:Button id="button1" text="Click Me" runat="server" /> 
</form> 

Notes About This Part of the Example

For simplicity, we have left out the form’s ACTION attribute, so the form will post to itself. Also, even though the Language attribute of the Page directive indicates C# as the language, you have not done anything language-specific yet. As we add more complex code to the example, we will show implementations in both C# and Visual Basic .NET.


At this point, the form does little other than maintain form state by using the runat="server" attribute of the ASP.NET server controls. Although you eventually want to use a dynamically generated ASP.NET field validator control, you start out simply by creating one the traditional way. After adding an ASP.NET RequiredFieldValidator control, your code now looks like Listing 3.8.

Listing 3.8. Adding a Static ASP.NET Validation Control
<%@ Page Language="C#" ClientTarget="DownLevel" %> 

<form id="frm1" runat="server"> 
     <asp:TextBox id="text1" runat="server" /> 
     <asp:RequiredFieldValidator id="valid1" 
          ControlToValidate="text1" 
          ErrorMessage="This field must contain a value!" 
          runat="server" /< 
     <br> 
     <asp:Button id="button1" text="Click Me" runat="server" /> 
</form> 

Your form now displays an error message if a value is not placed in the text field before the form is submitted. This implementation is not your final intention (remember, you wanted the field validator to be created dynamically), but at least you have a checkpoint to know that you’re on the right track to getting your form to work properly.

Adding Complexity

To dynamically create the field validator control, you need to implement the Page_Load event of your ASP.NET page. In this event, you create the field validator control and bind it to the form as shown in Listings 3.9 and 3.10.

Listing 3.9. Dynamically Creating ASP.NET Validation Control (C#)
<%@ Page Language="C#" ClientTarget="DownLevel" %> 

<script language="C#" runat="server"> 
void Page_Load(Object sender, EventArgs E) 
{
     if(IsPostBack) 
     {
           RequiredFieldValidator valid1 = new 
           RequiredFieldValidator(); 
                      valid1.ID = "valid1"; 
           valid1.ControlToValidate = "text1"; 
           valid1.ErrorMessage = 
               "This field must contain a value!"; 
           frm1.Controls.Add(valid1); 
          } 
} 
</script> 

<form id="frm1" runat="server"> 
      <asp:TextBox id="text1" runat="server" /> 
      <br> 
      <asp:Button id="button1" text="Click Me" runat="server" /> 
</form> 

Listing 3.10. Dynamically Creating ASP.NET Validation Control (Visual Basic .NET)
<%@ Page Language="VB" ClientTarget="DownLevel" %> 

<script language="VB" runat="server"> 
      Sub Page_Load(sender as Object, E as EventArgs) 
            If (IsPostBack) Then 
                  Dim valid1 As RequiredFieldValidator = _ 
                       New RequiredFieldValidator 
                 valid1.ID = "valid1" 
                 valid1.ControlToValidate = "text1" 
                 valid1.ErrorMessage = _ 
                       "This field must contain a value!" 
                  frm1.Controls.Add(valid1) 
            End If 
      End Sub 
</script> 

You have removed the ASP.NET validation control from the form definition and are now dynamically creating it in the Page_Load event. If you run this code, however, the validation does not take place. Why, you ask? Well, if you hadn’t taken the previous steps and reached a checkpoint, you would have absolutely no idea what the problem was.You did, however, so you know that it is not a problem with the validation logic. It must be a problem with the way you have implemented it. A little snooping around leads you to the conclusion that the form is being validated before the Page_Load event is fired, so your dynamic validation control is being created after the fact. To correct this, you must call the Validate() method of the Page object to re-evaluate the form based on your new validation object.

That’s not the only problem, however. Even after you call the Validate method, the error message is being rendered in the wrong place. It’s showing up after the Submit button instead of after the text field to which it references. The reason for this is that when you use the Add method of the form’s Controls collection, it appends the control to the end of the form. To insert the RequiredFieldValidator control after the text field, you must use the AddAt method of the form’s Controls collection and specify a control index. With a little trial and error, you can determine that an index of two puts the error message where you want it. The final code looks like that shown in Listings 3.11 and 3.12.

Listing 3.11. Fixing the Placement and Behavior of the Validation Control (C#)
<%@ Page Language="C#" ClientTarget="DownLevel" %> 

<script language="C#" runat="server"> 
void Page_Load(Object sender, EventArgs E) 
{
      if(IsPostBack) 
      {
           RequiredFieldValidator valid1 = new 
                 RequiredFieldValidator(); 
            valid1.ID = "valid1"; 
            valid1.ControlToValidate = "text1"; 
            valid1.ErrorMessage = 
                  "This field must contain a value!"; 
          frm1.Controls.AddAt(2,valid1); 
          Validate(); 
      } 
} 
</script> 

<form id="frm1" runat="server"> 
     <asp:TextBox id="text1" runat="server" /> 
     <br> 
     <asp:Button id="button1" text="Click Me" runat="server" /> 
</form> 

Listing 3.12. Fixing the Placement and Behavior of the Validation Control (Visual Basic .NET)
<%@ Page Language="VB" ClientTarget="DownLevel" %> 

<script language="VB" runat="server"> 
      Sub Page_Load(sender as Object, E as EventArgs) 
             If (IsPostBack) Then 
                   Dim valid1 As RequiredFieldValidator = _ 
                         New RequiredFieldValidator 
                   valid1.ID = "valid1" 
                   valid1.ControlToValidate = "text1" 
                   valid1.ErrorMessage = _ 
                         "This field must contain a value!" 
                   frm1.Controls.AddAt(2,valid1) 
                   Validate() 
             End If 
       End Sub 
</script> 

As you can see, starting out simple and gradually building complexity greatly reduces the amount of time that it takes to troubleshoot problems because you already know what parts definitely work.You can then dedicate your time to finding the problems with the parts that you are not certain of.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset