Introduction
This article first appeared on www.HowToDoThings.com
This article explains how to add error messages to a ValidationSummary
at runtime and have the addition of those message set Page.IsValid
to False
. This technique is useful when you do not know until runtime what constraints should apply to a webform, or when you want to validate against constraints which do not relate directly to a WebControl.
One of the requirements when writing www.howtodothings.com was the ability to model object constraints in OCL and then to validate the current page against those constraints.
The problem with normal validators is that they are designed to validate individual controls rather than a list of constraints on an object. The approach I took was to create a validator which I can place on any web form and add as many errors to as I required.
The first step was to create a WebControl which supported IValidator
public class MultiValidator : WebControl, IValidator
{
}
I then added an ArrayList to hold the error strings, and a method to add an error.
private ArrayList Errors = new ArrayList();
public void AddError(string message)
{
Errors.Add(message);
}
When ASP.NET validates a page it enumerates all IValidator
s within its own Validators property, and called IValidator.Validate()
. To determine if the page is valid or not it then checks IValidator.IsValid
.
To add custom error messages at runtime I decided to create a static validator class which always returns "false" from IsValidator.IsValid
. For each error message in my MultiValidator
I could then simply create an instance of one of these validators.
[ToolboxItem(false)]
internal class StaticValidator : IValidator
{
private string errorMessage;
#region IValidator
void IValidator.Validate()
{
}
bool IValidator.IsValid
{
get { return false; }
set { }
}
#endregion
public string ErrorMessage
{
get { return errorMessage; }
set { errorMessage = value; }
}
}
Now that the StaticValidator
was written, all I needed to do was to add the required IValidator
implementations to my MultiValidator class.
#region IValidator
void IValidator.Validate()
{
isValid = (Errors.Count == 0);
foreach(string error in Errors)
{
StaticValidator validator = new StaticValidator();
validator.ErrorMessage = error;
Page.Validators.Add(validator);
Validators.Add(validator);
}
}
bool IValidator.IsValid
{
get { return isValid; }
set { isValid = value; }
}
#endregion
Within a webform, I would now
- Set
CausesValidation
to false on my submit button.
- Validate my object.
- Call
MultiValidator1.AddError()
for each error encountered.
- Call
Page.Validate();
- Check
Page.IsValid
as normal.
Using a ValidationSummary I could then display the broken constraints to the user for rectification.
Using the code
To use the code, simply compile the two provided CS files into a WebControl assembly and then drop a MultiValidator onto your webpage. Errors may be added like so
if (SomeUnusualCondition)
multiValidator1.AddError("Something unusual is wrong");