In the WPF project I am working on I am considering implementing data validation through attributes on properties of my view models.
Example:
[RegexConstraint("^[A-Z][a-zA-Z]+$")]
public string Name
{
set
{
_name = value;
OnPropertyChanged("Name")
}
}
All my view models inherit from a common ViewModelBase class, which implements IDataErrorInfo. The indexer:
string IDataErrorInfo.this[string columnName]
retrieves properties by name (using reflection),
var properties = GetType().GetProperties().Where(p=> p.Name == "someName")
finds all constraint attributes…
private static ICollection<IValidator> GetValidations(PropertyInfo property)
{
return (ValidationAttribute[])property.GetCustomAttributes(typeof(ValidationAttribute), true))
.Select(va => new AttributeValidator(va)).Cast<IValidator>().ToList();
}
… and performs validation
It seems to work, but my question is – does anyone have experience using a similar technique? Is that a bad idea?
It does make my code seem cleaner and more concise, and I avoid having to implement IDataErrorInfo in all my view model classes, but on the other hand it creates a new problem – how to construct pretty user messages, when the validation logic relies on property names / attribute names rather than using hard-coded messages – like all the IDataErrorInfo examples I was able to find.
Summing up – my question is – should I continue going down this road, or should I use a different validation scheme?
I have done this similar technique on a couple of different projects and you can control the error message on most of the DataAnnotation attributes to make them more friendly. It is a completely viable solution as we done this recently on two larger WPF projects and are doing the same thing currently on a third. Now with the caveat… We did find ourselves having to create a lot of custom DataAnnotation classes to handle a lot of complex business rules, so it depends on the complexity of the business rules around your data. If you are primarily able to support validation in your app using mostly out-of-the-box DataAnnotations then you would not face this same challenge. As far as error messages go, you can set the named property on the DataAnnotation attribute like:
So you can pretty up messages for properties named like “FirstName” you can display in the message as “First Name is required…”.
Also, as long as you have done the work to wire everything up in your base class to IDataErrorInfo then you are golden in a WPF app. It does make your code much cleaner and minimizes what you have to write (except for the custom validation attributes if you need them).