Custom Validation in MVC/Web API Using Validation Attribute

Custom Validation is very useful when we are using the same property in a number of places in our application. Rather than adding AddModelError in ModelState, it is a good practice to create this in a separate reusable library so that we can use this in the project with a very consistent method and re-use in any other project. This should be a project independent library and reusable component.

Following are the steps to create Custom Validator and use it in view model classes.

  1. Create new class DateRangeAttribute inherit from ValidationAttribute
  2. Ensure value is of type DateTime, if not throw ValidationException.
  3. Create constructor to get values dynamically from the View Model.
  4. Override IsValid method of ValidationAttribute class and write logic to validate Date range.

Example

Date Range Attribute Class

  1. public class DateRangeAttribute: ValidationAttribute  
  2.   
  3. {  
  4.   
  5.     private int _endAge;  
  6.   
  7.     private int _startAge;  
  8.   
  9.     public DateRangeAttribute(int startAge, int endAge)  
  10.   
  11.     {  
  12.   
  13.         startAge = _startAge;  
  14.   
  15.         endAge = _endAge;  
  16.   
  17.     }  
  18.   
  19.     protected override ValidationResult IsValid(object value, ValidationContext validationContext)  
  20.   
  21.     {  
  22.   
  23.         if (!(value is DateTime))  
  24.   
  25.         {  
  26.   
  27.             throw new ValidationException("DateRange is valid for DateTime property only.");  
  28.   
  29.         } else  
  30.   
  31.         {  
  32.   
  33.             var date = (DateTime) value;  
  34.   
  35.             //Better to create DateTime extension method to calculate Age  
  36.   
  37.             if ((Calculate.GetAge(date) < _startAge) || (Calculate.GetAge(date) < _endAge))  
  38.   
  39.             {  
  40.   
  41.                 return new ValidationResult(this.FormatErrorMessage(validationContext.MemberName));  
  42.   
  43.             } else  
  44.   
  45.             {  
  46.   
  47.                 return ValidationResult.Success;  
  48.   
  49.             }  
  50.   
  51.         }  
  52.   
  53.     }  
  54.   
  55. }

Usage:

  1. public class User    
  2.     
  3. {    
  4.     [Required]    
  5.     
  6.     public string FirstName    
  7.     {    
  8.         get;    
  9.         set;    
  10.     }    
  11.     
  12.     [Required]    
  13.     
  14.     public string LastName    
  15.     {    
  16.         get;    
  17.         set;    
  18.     }    
  19.     
  20.     [DateRange(18, 100)]    
  21.     
  22.     public string BirthDate    
  23.     {    
  24.         get;    
  25.         set;    
  26.     }    
  27.     
  28. }