Validate data with WPF and Entity Framework using DataAnnotations?

.net data-annotations entity-framework validation wpf


Is there any way to validate using DataAnnotations in WPF & Entity Framework?

5/14/2012 3:40:18 PM

Accepted Answer

You can use the DataAnnotations.Validator class, as described here:

But if you're using a "buddy" class for the metadata, you need to register that fact before you validate, as described here:

  new AssociatedMetadataTypeTypeDescriptionProvider(typeof(myEntity), 

List<ValidationResult> results = new List<ValidationResult>();
ValidationContext context = new ValidationContext(myEntity, null, null)
bool valid = Validator.TryValidateObject(myEntity, context, results, true);

[Added the following to respond to Shimmy's comment]

I wrote a generic method to implement the logic above, so that any object can call it:

// If the class to be validated does not have a separate metadata class, pass
// the same type for both typeparams.
public static bool IsValid<T, U>(this T obj, ref Dictionary<string, string> errors)
    //If metadata class type has been passed in that's different from the class to be validated, register the association
    if (typeof(T) != typeof(U))
        TypeDescriptor.AddProviderTransparent(new AssociatedMetadataTypeTypeDescriptionProvider(typeof(T), typeof(U)), typeof(T));

    var validationContext = new ValidationContext(obj, null, null);
    var validationResults = new List<ValidationResult>();
    Validator.TryValidateObject(obj, validationContext, validationResults, true);

    if (validationResults.Count > 0 && errors == null)
        errors = new Dictionary<string, string>(validationResults.Count);

    foreach (var validationResult in validationResults)
        errors.Add(validationResult.MemberNames.First(), validationResult.ErrorMessage);

    if (validationResults.Count > 0)
        return false;
        return true;

In each object that needs to be validated, I add a call to this method:

public partial class Employee
    private sealed class Metadata
        [Email(ErrorMessage = "Please enter a valid email address.")]
        public string EmailAddress { get; set; }

    public bool IsValid(ref Dictionary<string, string> errors)
        return this.IsValid<Employee, Metadata>(ref errors);
        //If the Employee class didn't have a buddy class,
        //I'd just pass Employee twice:
        //return this.IsValid<Employee, Employee>(ref errors);
2/28/2011 2:17:41 AM

Popular Answer

I think that what is missing from Craigs answer is how to actually check if there are validation errors. This is DataAnnotation validation runner written by Steve Sanderson for those who want to run validation check in deferent layer then presentation ( , the code is in example project):

public static IEnumerable<ErrorInfo> GetErrors(object instance)
    var metadataAttrib = instance.GetType().GetCustomAttributes
        (typeof(MetadataTypeAttribute), true).
    var buddyClassOrModelClass = 
        metadataAttrib != null ? 
        metadataAttrib.MetadataClassType : 
    var buddyClassProperties = TypeDescriptor.GetProperties
    var modelClassProperties = TypeDescriptor.GetProperties

    return from buddyProp in buddyClassProperties
           join modelProp in modelClassProperties
               on buddyProp.Name equals modelProp.Name
           from attribute in buddyProp.Attributes.
           where !attribute.IsValid(modelProp.GetValue(instance))
           select new ErrorInfo(buddyProp.Name, 
               attribute.FormatErrorMessage(string.Empty), instance);

I'm not familiar with WPF (not sure if there is some out-of-the-box solution for you question), but maybe you can use it.

Also, there are some comments on his blog that in some cases it fails to evaluate validation rule properly but it never failed for me.

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow