Several people have asked me about using data annotations for validation outside of a UI framework, like ASP.NET MVC or Silverlight. The System.ComponentModel.DataAnnotations assembly contains everything you need to execute validation logic in the annotations. Specifically, there is a static Validator class to execute the validation rules. For example, let's say you have the following class in a console mode application:
public class Recipe { [Required] public string Name { get; set; } }
You could validate the recipe with the following code:
var recipe = new Recipe(); var context = new ValidationContext(recipe, serviceProvider: null, items: null); var results = new List<ValidationResult>(); var isValid = Validator.TryValidateObject(recipe, context, results); if (!isValid) { foreach (var validationResult in results) { Console.WriteLine(validationResult.ErrorMessage); } }
Result: "The Name field is required".
You can construct the ValidationContext class without a service provider or items collection, as shown in the above code, as they are optional for the built-in validation attributes. The Validator also executes any custom attributes you have defined, and for custom attributes you might find the serviceProvider useful as a service locator, while the items parameter is a dictionary of extra data to pass along. The Validator also works with self validating objects that implement IValidatableObject.
public class Recipe : IValidatableObject { [Required] public string Name { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { // ... } }
Like everything framework related, the Validator tries to provide an API that will work in a number of validation scenarios. I recommend you bend it to your will and build something that makes it easy to use inside your specific design and architecture. A class like the following would be a step towards hiding some complexity.
public class DataAnnotationsValidator { public bool TryValidate(object @object, out ICollection<ValidationResult> results) { var context = new ValidationContext(@object, serviceProvider: null, items: null); results = new List<ValidationResult>(); return Validator.TryValidateObject( @object, context, results, validateAllProperties: true ); } }