Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Better ValidationSummary Control for Data Driven Applications

0.00/5 (No votes)
10 Jun 2002 1  
The ValidationSummary Control can be easily subclassed to make data driven web applications more code-friendly.

Introduction

The validation controls that ship with ASP.NET go a long way towards reducing a lot of the tedious code you write in web pages. Already people are building on the concept of validation controls and providing customized versions to support specific data types that are common in many web applications. I want to demonstrate how a simple customization of the Validation Summary control can greatly clean up the code in your data driven web applications

Despite the power of the validation controls there are some validations that cannot ever be preformed on the client side. For example, validating that the user isn't entering duplicate information into your database. The CustomValidator control is made for our 'custom' code that must validate data entry but it is rather awkward because of the event model and concurrency issues inherent with web applications. Look at the code below to see what I mean. Notice we end up with a rather useless ServerValidate event handler. The only reason this can work is because the ValidationSummary control is smart enough not to render blank entries. Even though our CustomValidator is always invalid the output will still be normal because our custom validator will have a blank error message when everything is valid.

private void CustomValidator1_ServerValidate(object source, 
    System.Web.UI.WebControls.ServerValidateEventArgs args) {

    /* Since our 'custom validation' occurs at the database level we can't
    really do anything useful here.  If we checked our database in here for
    duplicates we'd be requiring a database call and plus there could still be
    the chance that another user inserts their data in-between the time we made that
    call and the time we actually did our insert.  Always return false so that our
    real validation code has a chance to set the error message */

    args.IsValid = false;
}

private void SaveButton_Click(object sender, System.EventArgs e) {    

    /* This is where we insert a new record into the database.
    We will get an exception from the data provider if we
    are going to violate any database rules.  If we get that
    exception we want to put a message in the validation 
    summary */

    try {
        BusinessLayer.InsertIntoDatabase(InputField.Text);
        Response.Redirect("success.aspx");
    }
    catch (SqlException ex){
        if (ex.Number == 2601){
            CustomValidator1.ErrorMessage = "That input already exists, try another";
        }
    }

    // All other exceptions are 'unexpected' so let global error handler 

    // deal with them


}

After writing this code a few times I figured there must be a better way. I then found the solution by simply subclassing the ValidationSummary control. With my custom control I'm able to programmatically add error messages whenever I need. The resulting code is much cleaner:

private void SaveButton_Click(object sender, System.EventArgs e) {    

    try {
        BusinessLayer.InsertIntoDatabase(InputField.Text);
        Response.Redirect("success.aspx");
    }
    catch (SqlException ex){
        if (ex.Number == 2601){
            CustomSummary.AddErrorMessage("That input already exists, try another");
        }
    }

}
The CustomSummary variable is an instance of my custom ValidationSummary control. Internally the AddErrorMessage is creating an internal class instance that implements the IValidator interface and adding it to the Page's Validators collection. Now that we haven't created a new validator the base behavior of the ValiationSummary control does the real work by iterating this collection and displaying the messages of instances marked invalid.
namespace Juranek.Web.Controls {
    /// <summary>

    /// This control inheirits the ASP.NET ValidationSummary control but adds

    /// the ability to dynamically add error messages without requiring 

    /// validation controls.

    /// </summary>

    public class ValidationSummary : System.Web.UI.WebControls.ValidationSummary
    {
        /// <summary>

        /// Allows the caller to place custom text messages inside the validation

        /// summary control

        /// </summary>

        /// lt;param name="msg">The message you want to appear in the summary</param>

        public void AddErrorMessage(string msg) {
            this.Page.Validators.Add(new DummyValidator(msg));
        }
    }

    /// <summary>

    /// The validation summary control works by iterating over the Page.Validators

    /// collection and displaying the ErrorMessage property of each validator

    /// that return false for the IsValid() property.  This class will act 

    /// like all the other validators except it always is invalid and thus the 

    /// ErrorMessage property will always be displayed.

    /// </summary>

    internal class DummyValidator : IValidator {

        private string errorMsg;

        public DummyValidator(string msg) {
            errorMsg = msg;
        }

        public string ErrorMessage{
            get{ return errorMsg;}
            set{ errorMsg = value;}
        }

        public bool IsValid{
            get{return false;}
            set{}
        }

        public void Validate() {
        }
    }

}

Overall with just a little bit of code you can make a much more intuitive ValidationSummary control.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here