Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending ASP.NET validators

I want to extend the asp.net validators such that I can make one validator dependent on another. The situation I have is that we have to validate a date in a textbox. Normally I would just use a combination of a RequiredFieldValidator (to ensure the date is provided), CompareValidator (to ensure the date is a date) and finally a RangeValidator (to ensure the date is within the required limit).

The problem with this is that the validators do not depend on each other, so as a result the user would see possibly all three messages at once for each validator when really all we want them to see is the most relevant message, i.e. if they entered "abc" in the date text box it would not be appropriate to show them the message saying the date was not in the valid range (even though technically I suppose this is true).

Currently to provide this kind of functionality we use a CustomValidator and just put all three validations within the server validate event handler and change the error message programmatically depending on what validation failed.

I would like to standardize this a bit more as it happens quite a bit in this application, I figure if I can make the validators dependent on each other this will solve the problem and also allow us to make use of the client side validation rather than having to do a postback especially to handle the custom validation.

The idea is that if one validator is dependent on another if that "master" is valid then the depended will perform its normal validation (EvaluateIsValid()) otherwise if the master validator is not valid then the other dependent validators will be valid.

I have come up with the following solution by inheriting from the various validator controls that already have been provided in the framework.

public class RequiredFieldDependentValidator : RequiredFieldValidator
{
    [Description("The validation control to depend on for determining if validation should occur")]
    public string ValidationControlToDependOn
    {
        get
        {
            object obj = ViewState["ValidationControlToDependOn"];
            if (obj != null) return (string) obj;
            return null;
        }
        set
        {
            Control control = FindControl(value);
            if (control is IValidator)
                ViewState["ValidationControlToDependOn"] = value;
            else
                throw new HttpException("ValidationControlToDependOn is not a validation control");
        }
    }

    protected override bool EvaluateIsValid()
    {
        IValidator validationControlToDependOn = FindControl(ValidationControlToDependOn) as IValidator;

        if(validationControlToDependOn != null)
        {
            return !validationControlToDependOn.IsValid || base.EvaluateIsValid();
        }

        return base.EvaluateIsValid();
    }

Currently I have just coded it for the RequiredFieldValidator, ideally I would like to provide this functionality for all of the validators but I cannot see a way to do this without copying the above code into a similar class for each individual type of validator I want to provide this functionality for thus if there are any problems I'm going to have to go back and change this code on each validator type individually.

Is there a way I can "centralise" this code and have it easily used in the validators without having to write the entire validators from scratch just so I can change the class they inherit from further down the line.

Cheers,

like image 517
Daniel Powell Avatar asked Aug 01 '10 06:08

Daniel Powell


1 Answers

You could override the Validate method in you page base. To add the validation dependency information in the page you can implement a not rendered control:

<my:ValidationDependency TargetControl="RegExp1" Dependency="Required1" />
like image 154
onof Avatar answered Nov 01 '22 23:11

onof