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

.net data-annotations entity-framework validation wpf

Question

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

Réponse acceptée

Vous pouvez utiliser la classe DataAnnotations.Validator, comme décrit ici:

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

Mais si vous utilisez une classe "buddy" pour les métadonnées, vous devez enregistrer ce fait avant de 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é le suivant pour répondre au commentaire de Shimmy]

J'ai écrit une méthode générique pour implémenter la logique ci-dessus, de sorte que tout objet puisse 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 à valider, j'ajoute 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);
    }
}

Réponse populaire

Je pense que ce qui manque à la réponse de Craigs est de savoir comment vérifier réellement s’il ya des erreurs de validation. Il s'agit du programme de validation DataAnnotation écrit par Steve Sanderson pour ceux qui souhaitent exécuter le contrôle de validation dans la couche de déférent, puis la 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 connais pas bien WPF (je ne sais pas s’il existe une solution prête à l'emploi pour votre question), mais vous pouvez peut-être l'utiliser.

En outre, il y a des commentaires sur son blog qui, dans certains cas, ne permettent pas d’évaluer correctement la règle de validation mais n’ont jamais échoué.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow