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) {
args.IsValid = false;
}
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){
CustomValidator1.ErrorMessage = "That input already exists, try another";
}
}
}
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 {
public class ValidationSummary : System.Web.UI.WebControls.ValidationSummary
{
public void AddErrorMessage(string msg) {
this.Page.Validators.Add(new DummyValidator(msg));
}
}
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.