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:
- public class Game
- {
- [Required]
- [StringLength(20)]
- public string Name { get; set; }
-
- [Range(0, 100)]
- public decimal Price { get; set; }
- }
To check if an instance is valid we can use the following code:
- Validator.TryValidateObject(obj
- , new ValidationContext(obj)
- , 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:
- static void Main(string[] args)
- {
- ICollection<ValidationResult> results = null;
-
- var invalidGame = new Game
- {
- Name = "My name is way over 20 characters",
- Price = 300,
- };
-
- if (!Validate(invalidGame, out results))
- {
- Console.WriteLine(String.Join("\n", results.Select(o => o.ErrorMessage)));
- }
- else
- {
- Console.WriteLine("I'm a valid object!");
- }
-
- Console.ReadKey(true);
- }
-
- static bool Validate<T>(T obj, out ICollection<ValidationResult> results)
- {
- results = new List<ValidationResult>();
-
- return Validator.TryValidateObject(obj, new ValidationContext(obj), results, true);
- }
After running, we will get the following output:
If we then change the properties to valid values:
- var validGame = new Game
- {
- Name = "Magicka",
- Price = 5,
- };
And test again:
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.
- public class DivisibleBy7Attribute : ValidationAttribute
- {
- public DivisibleBy7Attribute()
- : base("{0} value is not divisible by 7")
- {
- }
-
- protected override ValidationResult IsValid(object value, ValidationContext validationContext)
- {
- decimal val = (decimal)value;
-
- bool valid = val % 7 == 0;
-
- if (valid)
- return null;
-
- return new ValidationResult(base.FormatErrorMessage(validationContext.MemberName)
- , new string[] { validationContext.MemberName });
- }
- }
And in the object to be validated:
- [DivisibleBy7]
- public decimal Price { get; set; }
If the validation fails it will return the following error message:
A full list of validation attributes can be found in the
MSDN documentation.