Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the RequiresValidationContext property of ValidationAttribute class for?

With .NET Framework 4.5, the ValidationAttribute class now has a new Boolean property named RequiresValidationContext.

I have been digging for long time now and I couldn't find what this property is there for. The difault value for this is false and I initially thought that if this is set to false, the below method is called:

public virtual bool IsValid(object value)

If it is set to true, then the below one is called:

protected virtual ValidationResult IsValid(object value, ValidationContext validationContext);

It turns out that no matter what you set, the IsValid method which returns ValidationResult is always called.

For the love of God, what is this RequiresValidationContext property for?

like image 252
tugberk Avatar asked Sep 25 '12 14:09

tugberk


People also ask

What is ValidationAttribute?

ValidationAttribute class is included in the DataAnnotations namespace. It helps you to validate the model data received from the user. It gives you many inbuilt validation attributes like StringLength, Required, DataType for validating the model.

Which base class does a custom validation attribute need to implement?

ValidationAttribute is abstract class and it is use as base class of various inbuilt validation attribute like required, stringlength, etc. With help of ValidationAttribute class we can create our own new validation attribute.


1 Answers

The RequiresValidationContext is useful for validator like CompareAttribute or custom attribute.

ValidationAttribute is abstract class and it depends what implementation you mean. For example I have Validation Attribute that check that some fields are required only if another property has some value.

It depends on Attribute implementation if the IsValid(object value) is called or not. For example:

[Display(Name = "Your employer")]
[LoginTypeRequired(LoginType = LoginType.Employee, ErrorMessage = "Employee must fill in Employer.")]
public int? Employer { get; set; }

Attribute code:

public class LoginTypeRequiredAttribute : RequiredAttribute
{
     public override bool RequiresValidationContext
     {
          get {return true;} 
     }

     public LoginType LoginType { get; set; }

     protected override ValidationResult IsValid(object value, ValidationContext validationContext)
     {
          RegisterModel model = (RegisterModel)validationContext.ObjectInstance;

          if (LoginType != model.LoginType)
              return null;
          else
              return base.IsValid(value, validationContext);
      }

       public override bool IsValid(object value)
       {
          return base.IsValid(value);
        }
}

The first method with two parameters use IsValid(object value, ValidationContext validationContext) to do the job with the context. If it is everything alright, it call the base and the internal .NET 4.5 stack is:

LinqDataModel.dll!LinqDataModel.Models.LoginTypeRequiredAttribute.IsValid(object value) Line 92 C# System.ComponentModel.DataAnnotations.dll!System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) + 0x74 bytes

LinqDataModel.dll!LinqDataModel.Models.LoginTypeRequiredAttribute.IsValid(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) Line 87 + 0xe bytes C# System.ComponentModel.DataAnnotations.dll!System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(object value, System.ComponentModel.DataAnnotations.ValidationContext validationContext) + 0x1e bytes
System.Web.Mvc.dll!System.Web.Mvc.DataAnnotationsModelValidator.Validate.MoveNext() + 0xa2 bytes System.Web.Mvc.dll!System.Web.Mvc.ModelValidator.CompositeModelValidator.Validate.MoveNext() + 0x138 bytes System.Web.Mvc.dll!System.Web.Mvc.DefaultModelBinder.OnModelUpdated(System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext) + 0x212 bytes

So, you can see that the case IsValid(object value, ValidationContext validationContext) is calling IsValid(object value) if not override.

But still you have the chance to override IsValid(object value, ValidationContext validationContext) and not to call the base.

like image 51
Tomas Kubes Avatar answered Oct 21 '22 06:10

Tomas Kubes