Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Custom Validation Summary

4.50/5 (10 votes)
1 Dec 2010CPOL3 min read 53.7K   379  
A Custom Validation Summary that supports multi-validation Groups

Introduction

One month ago, I was working on an ASP.NET project that am I still working on and I came a cross a point where I wanted to have a centralized Validation Summary and Multi-Validation Groups. Of course, with no hesitation I added a centralized validation summary and started to do my validation ... but unfortunately, I wasn't lucky enough for that to work !!!

The Problem !!!

At the beginning, I thought I was doing something wrong, my scenario was more than basic and very EXPECTED to occur, two set of controls, each one with a validation group, and one validation summary. I do my validation on the server side using Page.Validate(ValidationGroupName) for each one as follows:

C#
Page.Validate("ValidationGroup1");
Page.Validate("ValidationGroup2");
if (Page.IsValid)
{
    //Do Something when validation successes 
}
else
{
    //Do something else when validation fails
} 

The funny thing is that if I wanted to show Validation Messages from both ValidationGroup1 and ValidationGroup2, I have to have TWO validation summaries, the first one is set to use the ValidationGroup1 and the other one is set to use the ValidationGroup2. In other words for each validation group you have or is going to occur in that page, you have to have n validation summaries.

Now that made me angry enough to have my own validation summary.

The Investigation

To solve this problem, I started with the Internet, searching for an article, a post or a blog that has the solution to such a basic scenario which is occurring for years now! Unbelievably I couldn't find a descent solution ! and I mean it ! The best thing I found is something that involved creating duplicate validators at runtime and adding them to the host page. I know it sounds crazy, but seriously that was the best solution !!

So I started to investigate the ASP.NET Validation Summary control itself, I took a sneak peak into its source code to figure out why it's not supporting more than one validation group and I found the below:

C#
internal string[] GetErrorMessages(out bool inError)
{
    string[] strArray = null;
    inError = false;
    int num = 0;
    ValidatorCollection validators = this.Page.GetValidators(this.ValidationGroup);
    for (int i = 0; i < validators.Count; i++)
    {
        IValidator validator = validators[i];
        if (!validator.IsValid)
        {
            inError = true;
            if (validator.ErrorMessage.Length != 0)
            {
                num++;
            }
        }
    }
    if (num != 0)
    {
        strArray = new string[num];
        int index = 0;
        for (int j = 0; j < validators.Count; j++)
        {
            IValidator validator2 = validators[j];
            if ((!validator2.IsValid && (validator2.ErrorMessage != null)) && 
		(validator2.ErrorMessage.Length != 0))
            {
                strArray[index] = string.Copy(validator2.ErrorMessage);
                index++;
            }
        }
    }
    return strArray;
}

Note the Italic bolded line of code; the validation summary uses its host page to get the validators with the same validation group as that of the validation summary !! Therefore there is no way it gets more than one validation group to be supported ! Of course, the GetValidators(ValidationGroupName) method doesn't treat null or empty validation group as a special case, it's another case as if you have specified a validation group, so only one validation group will be retrieving its validators.

The Solution

To solve this issue, at first I thought of having a Custom Control that behaves exactly as the Current ASP.NET Validation Summary with extra feature of enabling to support any validation group on the hosting page.

First, I have simply added a new Enumeration ValidationGroupMode:

C#
/// <summary>
/// The way the validation summary shall behave toward validation groups.
/// </summary>
public enum ValidationGroupMode
{
    /// <summary>
    /// Only one validation group will be registered to the validation summary.
    /// (This will make this validation summary act just like the 
    /// ASP.NET validation summary.)
    /// </summary>
    SingleValidationGroup = 0,
    /// <summary>
    /// All validation groups will be registered in the validation summary.
    /// </summary>
    AllValidationGroups = 1
} 

Secondly, I tweaked the GetErrorMessages method to become as follows:

C#
internal string[] GetErrorMessages(out bool inError)
    {
        string[] strArray = null;
        inError = false;
        int num = 0;
        ValidatorCollection validators
            = this.ValidationGroupMode == ValidationGroupMode.AllValidationGroups ? 
		this.Page.Validators : this.Page.GetValidators(this.ValidationGroup);
        for (int i = 0; i < validators.Count; i++)
        {
            IValidator validator = validators[i];
            if (!validator.IsValid)
            {
                inError = true;
                if (validator.ErrorMessage.Length != 0)
                {
                    num++;
                }
            }
        }
        if (num != 0)
        {
            strArray = new string[num];
            int index = 0;
            for (int j = 0; j < validators.Count; j++)
            {
                IValidator validator2 = validators[j];
                if ((!validator2.IsValid && (validator2.ErrorMessage != null)) 
			&& (validator2.ErrorMessage.Length != 0))
                {
                    strArray[index] = string.Copy(validator2.ErrorMessage);
                    index++;
                }
            }
        }
        return strArray;
    }

Simply in case I wanted to have all validation groups to share the same validation summary, I got all validators on the page using this.Page.Validators.

Final Words

I hope this article was useful, and I am attaching the code for the Custom Validation Summary. I made sure that it's compatible with Framework 2.0 and above.

History

  • V 1.0 Created the article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)