Control the order of Attribute Based Validation and Stop the firing of Validation on First Failure

Topics: Validation Application Block
Feb 21, 2011 at 12:33 PM

Hi,

I am trying to achieve the following, would like to know how to achieve this.

There is a property on my domain object which needs to be validated. I have 3 validators on that property

        [StringLengthValidator(6, 50, MessageTemplate = "UserName Not valid!!! Please enter between 10 and 25 characters.", Ruleset = "Users")]
        [NotNullValidator(Ruleset = "Users", MessageTemplate = "UserName Is Null!!!")]
        [RegexValidator("[a-z]",Ruleset = "Users", MessageTemplate = "Not a alphabet")]
        public string UserName
        {
            get { return mUserName; }
            set { mUserName = value; }
        }
        private string mUserName;
I have two requirements

  •  The requirement is how do I control the order of execution of these validators. Though I know a group of validations get fired at one stretch like Required field validators then Range Validators etc. I would like to find out how do I control the order of execution of individual groups and then also the complete execution.
  • Now once I could control the order of execution, I would like the execution to stop on the first validation failure. i.e. As the validations starts firing one by one on the domain object the moment a validation fails, no more validation is to be fired and the last validation error is returned.

I am aware of two composite validations "AndCompositeValidator" and "OrCompositeValidator", would like to know when is the respective types created, and do these give any advantage of controlling the order.

I am also aware of Validation Handlers being able to have order named property, but would like to know how to use it and does it any way help me in fulfilling my requirement.

Pankaj

Feb 22, 2011 at 6:57 AM

As far as I know, you cannot intercept the execution of each validators. As what you have also observed all validators is being assess all at once. And I'm not aware of any workaround on how will be the best approach to address your scenario.

As for CompositeValidator, these validators are ussually used in cases where complex validation logic is needed. Especially if you would need to group some validators. I also don't think this may be useful for identifying the order of your validators. (For references on CompositeValidator you can also check the documentation for more details - And Composite Validator and Or Composite Validator).

And as for the Validation Call Handlers, it is specifically being used in Policy Injection in cases you would want to implement an interception that will trigger calling EntLib's Validation App Block. The Order Property is actually a common property for all the call handlers which specifies the position of the handler within the policy handler chain.

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 1, 2011 at 6:10 PM

Thanks for the information.

We solved the problem by creating a validator of our own derived from the base validator.

Pankaj

May 10, 2011 at 2:57 PM

Hi, even with a custom validator derived from the base validator, how can it resolve the problem of validation firing order ?

May 11, 2011 at 6:25 AM

Hi,

Inside the DoValidate method of your custom validator, you can have nested conditions so it may look like you are validating in order. Here is a simple example of an email domain validator:

 public EmailDomainValidator()
      : base(nullnull)
{
      _domains = new List<string>(new string[] { ".com"
".net"".gov"".org"".edu", ".mil" });
}
 
public EmailDomainValidator(params string[] acceptedDomains)
      : base(nullnull)
{
      _domains = new List<string>(acceptedDomains);
}

 
protected override void DoValidate(string objectToValidate, object
  currentTarget, string key, ValidationResults validationResults)
{
  if (!string.IsNullOrEmpty(objectToValidate) && objectToValidate.Length >= 6)
  {
    string extension = 
 objectToValidate.Substring(objectToValidate.LastIndexOf
      ('.'));
 
    if (!_domains.Contains(extension))
      validationResults.AddResult(new ValidationResult(@
        "The email address domain is not acceptable ", 
 currentTarget, key, null,
        this));
  }
  else
    validationResults.AddResult(new ValidationResult(@
      "The email address must be longer ", 
 currentTarget,key, nullthis));
}

In the example, you can see that it validates first if the email is null or empty or is greater than 6 characters. If the conditions are met, then it will proceed validating the domain otherwise it will return "The email address must be longer" message.

 

Noel Angelo Bolasoc
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com