Using Data Annotations to Validate Models in .NET

The .NET Framework provides a set of attributes that we can use to validate objects. By using the namespace System.ComponentModel.DataAnnotations we can annotate our model's properties with validation attributes.
 
There are attributes to mark a property as required, set a maximum length, and so on. For example:
  1. public class Game    
  2. {    
  3.     [Required]    
  4.     [StringLength(20)]    
  5.     public string Name { getset; }    
  6.      
  7.     [Range(0, 100)]    
  8.     public decimal Price { getset; }    
  9. }   
To check if an instance is valid we can use the following code:
  1. Validator.TryValidateObject(obj    
  2.     , new ValidationContext(obj)    
  3.     , results, true);   
The value returned is true if the object does not have any errors or false if it does have errors. And the parameter results are populated with errors if any. The full definition of this method can be found in the MSDN documentation.
 
To test our Game class we can use the following code:
  1. static void Main(string[] args)    
  2. {    
  3.     ICollection<ValidationResult> results = null;    
  4.      
  5.     var invalidGame = new Game    
  6.     {    
  7.         Name = "My name is way over 20 characters",    
  8.         Price = 300,    
  9.     };    
  10.      
  11.     if (!Validate(invalidGame, out results))    
  12.     {    
  13.         Console.WriteLine(String.Join("\n", results.Select(o => o.ErrorMessage)));    
  14.     }    
  15.     else    
  16.     {    
  17.         Console.WriteLine("I'm a valid object!");    
  18.     }    
  19.      
  20.     Console.ReadKey(true);    
  21. }    
  22.      
  23. static bool Validate<T>(T obj, out ICollection<ValidationResult> results)    
  24. {    
  25.     results = new List<ValidationResult>();    
  26.      
  27.     return Validator.TryValidateObject(obj, new ValidationContext(obj), results, true);    
  28. }  
After running, we will get the following output:
 
results
 
If we then change the properties to valid values:
  1. var validGame = new Game    
  2. {    
  3.     Name = "Magicka",    
  4.     Price = 5,    
  5. };  
And test again:
 
test
 
It is also possible to create your own attributes. All you need to do is inherit fromValidationAttribute. In the following example, the attribute will check if the value is divisible by 7. If not then it will return an error message.
  1. public class DivisibleBy7Attribute : ValidationAttribute    
  2. {    
  3.     public DivisibleBy7Attribute()    
  4.         : base("{0} value is not divisible by 7")    
  5.     {    
  6.     }    
  7.      
  8.     protected override ValidationResult IsValid(object value, ValidationContext validationContext)    
  9.     {    
  10.         decimal val = (decimal)value;    
  11.      
  12.         bool valid = val % 7 == 0;    
  13.      
  14.         if (valid)    
  15.             return null;    
  16.      
  17.         return new ValidationResult(base.FormatErrorMessage(validationContext.MemberName)    
  18.             , new string[] { validationContext.MemberName });    
  19.     }    
  20. }    
And in the object to be validated:
  1. [DivisibleBy7]   
  2. public decimal Price { getset; }   
If the validation fails it will return the following error message:
 
price value
 
A full list of validation attributes can be found in the MSDN documentation.