views:

90

answers:

2

I'd like to use the data validation attributes in a library assembly, so that any consumer of the data can validate it without using a ModelBinder (in a console application, for instance). How can I do it?

A: 

The System.ComponentModel.DataAnnotations.ValidationAttribute classes have IsValid() methods that perform the validation logic. They take an Object (the value of the field they decorate) and return true or false.

You can use these attributes, and a little reflection, to roll your own aspect-oriented validator. Pass your validator an object, and the validator will get a list of PropertyInfos and FieldInfos. For each of these, it can call GetCustomAttributes() to look for those that inherit from ValidationAttribute, and for each of these, call IsValid(), passing the value of the property or field. This can be done totally dynamically without knowing the structure of the class to be validated at design-time.

KeithS
+1  A: 

Actually this is pretty cool. I used it in a WFP validation implementation recently. Most people end up writing lots of code using reflection to iterate the attributes, but there's a built in function for this.

       var vc = new ValidationContext(myObject, null, null);
       return Validator.TryValidateObject(myObject, vc, null, true);

You can also validate attributes on a single named property. You can also optionally pass in a list in order to access the error messages:

       var results = new List<ValidationResult>();
       var vc = new ValidationContext(myObject, null, null) { MemberName = "UserName"};
       var isValid = Validator.TryValidateProperty(value, vc, results);

       // get all the errors
       var errors = Array.ConvertAll(results.ToArray(), o => o.ErrorMessage);
TheCodeKing
I ended up writing a lot of reflection code to do this while I waited on an answer :(
Chris McCall
Yeah surprisingly few examples around using this API, and loads using reflection!
TheCodeKing
not a huge fan of output parameters, so I raised a custom exception instead (impossible to ignore)
Chris McCall