To read the article online, visit http://www.4GuysFromRolla.com/articles/112404-1.aspx

Creating a TextBoxLengthValidator Validator Control

By Scott Mitchell and Jisun Lee


Introduction


When collecting input from a user, it is important to ensure that the input received meets the requirements of the system. For example, when placing an order at a site like Amazon.com it is vital that the user supply certain required bits of information, such as the shipping address and their payment information. Also, the system may expect data in a specified format, or adhering to some other constraint. A common task for Web developers prior to ASP.NET was writing code that would ensure that the data submitted by a user met the system's specific requirements. ASP.NET, however, greatly simplified this through its validation controls, which are a set of Web controls designed specifically to validate input data.

You've no doubt had experience using the built-in ASP.NET validation controls: the RequiredFieldValidator is used to ensure that the user provides a value for a TextBox or DropDownList; the CompareValidator can be used to ensure that the value entered into a TextBox is of a specific type (such as String, Numeric, Date, etc.), or can compare a TextBox value to a static value or to a value in another TextBox; the RangeValidator ensures that a value entered is within an acceptable range; and the RegularExpressionValidator can be used to check that a value entered conforms to a specified regular expression (useful for ensuring that data is entered in a certain format, such as phone numbers, email addresses, social security numbers, etc.).

While these validation controls provide most validation support you'll need, what if you need to implement some other type of validation not provided by these controls? One option is to use the CustomValidator. With the CustomValidator you must provide a custom server-side method to validate the data, and an optional client-side function. (For more information on using CustomValidators be sure to read Using the CustomValidator Control.)

Another option for providing custom validation is to create your own validation server control. This approach is ideal to the CustomValidator approach if you know that you are going to be using this validation on multiple pages or in more than one project. By creating a custom validation server control you can plop down the custom control on your page just like you would any other validation control. You don't have to write any extra code or logic for your custom validation as it's all wrapped up in the custom control. Furthermore, utilizing the control in other Web applications is as simple as copying over the custom control's assembly (.dll file) into the other Web application's /bin directory. In this article we'll look at how to create a custom validation control that ensures that the number of characters entered into a TextBox is less than or equal to some prescribed number.

Limiting the Number of Characters Entered Into a Form Field


There are many situations in which we may want to limit the number of characters a user can enter into a form field. For example, if the data entered by the user is being stored in a database, a form field's corresponding database field might be configured to only hold, say, 50 characters. Therefore, we want to ensure that the user does not provide a value that contains more than 50 characters. Furthermore, certain types of input may require that the number of characters not exceed a certain length.

One option to limiting the number of characters a user can provide in a TextBox is to set the TextBox's MaxLength property. For browsers that support this attribute, this will prevent the user from entering more than the specified number of characters. This is one approach to limiting the number of characters a user can enter into a TextBox, but it is not a complete solution since it only works client-side; that is, there's no automatic server-side check on postback to ensure that the data submitted does not exceed the specified MaxLength (what it boils down to is that you have to write this code). A nefarious user circumvent the effects of the MaxLength property by saving the page's HTML markup on his computer, taking out the TextBox's maxlength attribute, and visiting this altered page. The downside, as aforementioned, is that you have to not forget to add a server-side check on postback to ensure that the data submitted by the user actually does contain no more than the maximum number of characters. Another downside of MaxLength is that the browser prevents new characters from being entered into the TextBox that would exceed the TextBox's specified maximum length. This can be annoying in certain situations: say you have a TextBox with MaxLength equal to 3. Now, say the user types in the value 124, and then realizes the want 144 instead. They might think to themselves, I'll put the cursor between the 1 and 2, type 4, and then hit Delete. However, when they try to hit 4, it won't let them, since it would exceed the TextBox's maximum length. Rather, they'd have to first delete 2 and then enter 4. (Not a huge deal, but it could frustrate an end user who is used to entering and then deleting, rather than the other way around.)

Better approaches include using a CustomValidator or a RegularExpressionValidator. With a CustomValidator you could write the necessary server-side and (optionally) client-side code to validate a field's length. With a RegularExpressionValidator you can specify that the input must contain a certain number of characters, like between 0 and 100 characters, or more fine-grained, like between 5 and 10 characters. For more information on using a RegularExpressionValidator in this manner refer to this newsgroup post by Peter Blum.

While the RegularExpressionValidator approach works, I prefer to create a custom validation server control myself. By using a validation control you would not need to write any server-side code other than the check to ensure Page.IsValid is True, nor would you need to bother with the details of a regular expression. If you are already familiar with using validation controls, having a custom validation control to ensure the TextBox's length is within a certain bounds will seem very natural to use - simply plop down the validation control on a page, specify the control to validate, and set finally set the MaximumLength property. That's all there is to it! In the remainder of this article we'll be building a custom validation server control called TextBoxLengthValidator, which, as its name implies, ensures that a TextBox's length is less than or equal to a specified value.

Creating the TextBoxLengthValidator


All of the ASP.NET validation controls are derived from the System.Web.UI.WebControls.BaseValidator class. The BaseValidator class contains a number of protected methods that provide important functionality that our custom validation server control will need to override. The most important one is EvaluateIsValid(), which returns a Boolean value indicating whether or not the value being validated is valid or not. The BaseValidator class also contains a number of properties that are common to all validators, such as ErrorMessage and ControlToValidate. By having our custom validation control derive from BaseValidator we do not have to provide these properties. There is one property, however, our TextBoxLengthValidator needs: an integer property that the page developer can set to specify the maximum number of characters that can appear in the TextBox specified in the ControlToValidate property.

The following code shows the MaximumLength property and overridden EvaluateIsValid() method for the custom validation control (the complete code can be downloaded at the end of this article):

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace skmExtendedValidators
{
   [ToolboxData("<{0}:TextBoxLengthValidator runat=server 
         ErrorMessage=\"TextBoxLengthValidator\"></{0}:TextBoxLengthValidator>")]
   public class TextBoxLengthValidator : BaseCompareValidator
   {

      // Properties
      [Bindable(true), 
       Description("TextBoxLengthValidator_MaximumLength"), 
       Category("Behavior"), 
       DefaultValue(-1)]
      public int MaximumLength
      {
         get
         {
            object MaxLengthVS = this.ViewState["MaximumLength"];
            if (MaxLengthVS != null)
            {
               return (int) MaxLengthVS;
            }
            return -1;
         }
         set
         {
            this.ViewState["MaximumLength"] = value;
         }
      }
 
      protected override bool EvaluateIsValid()
      {
         if (this.MaximumLength < 0)
            return true;

         string ControlToValidateName = 
             base.GetControlValidationValue(base.ControlToValidate);

         return ControlToValidateName.Length <= 
                   System.Convert.ToInt32(this.MaximumLength);
      }
      
      ...
   }
}

In the EvaluateIsValid() method the value of the control specified by the ControlToValidate property can be grabbed via the BaseValidator's GetControlValidationValue(). Once we have this value (which is a String value), we return True if the String's length is less than or equal to the MaximumLength property, and False otherwise. (Note: giving MaximumLength a value less than 0 disables the validation control; that is, if MaximumLength is less than 0, then any length input will pass as valid.)

Adding Client-Side Validation


The code presented so far is sufficient to build a validation control that does not utilize client-side validation, but just server-side validation. It's vital that we provide server-side validation, since all validation controls should do so, but by omitting client-side validation we are worsening the user experience for those visiting the site with an uplevel browser. The built-in ASP.NET validation server controls provide client-side validation in the following manner: in their AddAttributesToRender() method the controls add an attribute to their rendered HTML element called evaluationfunction that specifies the JavaScript function to call to perform client-side validation. If any other additional parameters are needing, these are added via attributes in this method as well. (For example, the RegularExpressionValidator needs to pass along the value of the ValidationExpression property, and does so through an HTML attribute named validationexpression.) The JavaScript functions specified in these attributes are pre-defined functions in the file WebUIValidation.js, which a reference is added to the page when any validation controls are used. (The WebUIValidation.js file can be found in the /aspnet_client/system_web/VERSION_NUMBER folder in your Web site's root physical directory.)

In order to add client-side support for the TextBoxLengthValidator validation control we need to specify what client-side function to call and what parameters to pass it. This information, as with the other validation controls, can be specified in the AddAttributesToRender() method. The challenge is that the WebUIValidation.js file does not contain a function for ensuring that the length of a TextBox is indeed less than some value. We have to write that ourselves. We have two options here:

  1. Modify WebUIValidation.js by hand, adding the necessary function
    • Pros: Once this file is modified our TextBoxLengthValidator will work just like any other validation control. All necessary script will be stashed in a single .js file, which the browser can cache.
    • Cons: We have to modify a system file. Also, if we want to take this functionality to other Web servers, we must modify their WebUIValidation.js file as well.
  2. Have our custom validation control inject the necessary JavaScript function directly into the ASP.NET page's rendered output.
    • Pros: This solution works without needing to modify a system file. Makes deployment easier.
    • Cons: Adds a bit of "weight" to each page that cannot be cached by a browser like an external JavaScript file could.
You can choose whatever option suits you best, but the TextBoxLengthValidator validation control has been implemented to use the latter approach: the necessary JavaScript is injected by the control to ease deployment. (You can implement the former technique by removing the code from the TextBoxLengthValidator control that injects the client-side code, moving it to the WebUIValidation.js file instead.) The following code adds the client-side functionality to the TextBoxLengthValidator control:

namespace skmExtendedValidators
{
   [ToolboxData("<{0}:TextBoxLengthValidator runat=server 
         ErrorMessage=\"TextBoxLengthValidator\"></{0}:TextBoxLengthValidator>")]
   public class TextBoxLengthValidator : BaseCompareValidator
   {
      ...

      protected override void AddAttributesToRender(HtmlTextWriter writer)
      {
         base.AddAttributesToRender(writer);
         if (base.RenderUplevel)
         {
            writer.AddAttribute("evaluationfunction", "TextBoxLengthValidatorIsValid");
            writer.AddAttribute("maximumlength", this.MaximumLength.ToString());
         }
      }
 
      protected override void OnPreRender(EventArgs e)
      {
         base.OnPreRender(e);

         if (base.RenderUplevel)
            Page.RegisterClientScriptBlock("TxtBxLngthValIsValid", 
               @"<script language='javascript'>
               function TextBoxLengthValidatorIsValid(val) 
               { 
                  var value = ValidatorGetValue(val.controltovalidate); 
                  if (ValidatorTrim(value).length == 0) return true; 
                  if (val.maximumlength < 0) return true; 
                  return (value.length <= val.maximumlength);
               }
            </script>");
      }
   }
}

Like the server-side EvaluateIsValid() method, the client-side TextBoxLengthValidatorIsValid() function returns True if the data being validated is valid, and False otherwise. In the AddAttributesToRender() method the client-side function to use and the parameter are specified (evaluationfunction is set to TextBoxLengthValidatorIsValid(); maximumlength is set to the value of the MaximumLength property). In the OnPreRender() method the necessary JavaScript is injected into the page. (For more information on injecting client-side script into a page from server-side code be sure to read my articles Working With Client-Side Script and Injecting Client-Side Script from an ASP.NET Server Control.)

As with the ASP.NET validation controls, the TextBoxLengthValidator control renders client-side validation script only for Internet Explorer. This is because the BaseValidator control emits JavaScript that only works in IE (namely, it uses document.all). This will be fixed in ASP.NET 2.0, but for ASP.NET 1.x you'll need to essentially reinvent the wheel and create your own BaseValidator class. I discuss this at more length in my article Client-Side Validation in Downlevel Browsers.

Using the TextBoxLengthValidator Control on an ASP.NET Page


The download accompanying this article contains the complete source code for the TextBoxLengthValidator validation control, along with a precompiled assembly for ASP.NET 1.1. If you are using Visual Studio .NET 2003, first add the TextBoxLengthValidator control to the Toolbox (right-click on the Toolbox and choose to Add/Remove Items, browse to the TextBoxLengthValidator assembly and click OK); then you can simply drag and drop the TextBoxLengthValidator control onto your ASP.NET pages. If you are using Visual Studio .NET 2002 (i.e., ASP.NET 1.0), you'll need to compile the code first. Create a new Web Control Library project, add the .cs file, and build the solution. Repeat the instructions for VS.NET 2003 using this newly compiled assembly.

If you are not using Visual Studio .NET you'll need to manually add the assembly to the /bin directory of your Web application. On pages that you want to use the control, add the following @Register directive to the top of the page: <%@ Register TagPrefix="skm" Namespace="skmExtendedValidators" Assembly="skmExtendedValidators" %>. Then, wherever you want the control to be added, just use: <skm:TextBoxLengthValidator runat="server" ... />. To see a working example be sure to check out the live demo.

That, basically, sums up the control (and, therefore, the article!). You can download the complete code at the end of this article. Also, there's a live demo to try that demonstrates the TextBoxLengthValidator validation control in action.

Happy Programming!

  • By Scott Mitchell and Jisun Lee


    Attachments:


  • Download the Complete Code (in ZIP format)

  • Article Information
    Article Title: ASP.NET.Creating a TextBoxLengthValidator Validator Control
    Article Author: Scott Mitchell
    Published Date: November 24, 2004
    Article URL: http://www.4GuysFromRolla.com/articles/112404-1.aspx


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers