35 votes

Valider les données en utilisant DataAnnotations avec WPF & Entity Framework?

Existe-t-il un moyen de valider l'utilisation de DataAnnotations dans WPF et Entity Framework?

46voto

Jeremy Gruenwald Points 1112

Vous pouvez utiliser le DataAnnotations.Classe de validation, comme décrit ici:

http://johan.driessen.se/archive/2009/11/18/testing-dataannotation-based-validation-in-asp.net-mvc.aspx

Mais si vous êtes à l'aide d'un "camarade" de classe pour les métadonnées, vous devez vous inscrire avant de vous valider, comme décrit ici:

http://forums.silverlight.net/forums/p/149264/377212.aspx

TypeDescriptor.AddProviderTransparent(
  new AssociatedMetadataTypeTypeDescriptionProvider(typeof(myEntity), 
    typeof(myEntityMetadataClass)), 
  typeof(myEntity));

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

[Ajouté ce qui suit à répondre à Shimmy commentaire]

J'ai écrit une méthode générique pour implémenter la logique ci-dessus, de sorte que n'importe quel objet peut l'appeler:

// 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;
    else
        return true;
}

Dans chaque objet qui doit être validé, j'ai ajouter un appel à cette méthode:

[MetadataType(typeof(Employee.Metadata))]
public partial class Employee
{
    private sealed class Metadata
    {
        [DisplayName("Email")]
        [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);
    }
}

4voto

Misha N. Points 2535

Je pense que ce qui est absent de Craigs réponse est comment pour vérifier si il y a des erreurs de validation. C'est DataAnnotation validation coureur écrit par Steve Sanderson pour ceux qui veulent courir contrôle de validation dans déférents couche puis présentation (http://blog.codeville.net/category/xval/ , le code est dans l'exemple de projet):

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

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

Je ne suis pas familier avec WPF (pas sûr si il ya un peu out-of-the-box solution pour vous en question), mais peut-être que vous pouvez l'utiliser.

Aussi, il y a quelques commentaires sur son blog, dans certains cas, il ne parvient pas à évaluer la validation de la règle correctement, mais il n'a jamais failli pour moi.

3voto

jbe Points 4629

Vous pouvez être intéressé par l'exemple d'application BookLibrary du WPF Application Framework (WAF) . Il fait exactement ce que vous demandez: utiliser DataAnnotations dans WPF & Entity Framework.

1voto

Guillaume Gros Points 141

J'ai eu la même question et trouvé les idées suivantes:

0voto

Craig Stuntz Points 95965

Utilisez une "classe de copain". Numéro 4 dans ce tutoriel .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X