Valider les données en utilisant DataAnnotations avec WPF & Entity Framework?
Existe-t-il un moyen de valider en utilisant DataAnnotations dans WPF & Entity Framework?
7 réponses
Vous pouvez utiliser les DataAnnotations.Classe Validator, comme décrit ici:
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é ce qui suit pour 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'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);
}
}
Je pense que ce qui manque à la réponse de Craigs est de savoir comment vérifier s'il y a des erreurs de validation. Ceci est dataannotation validation runner écrit par Steve Sanderson pour ceux qui veulent exécuter la vérification de validation dans la couche déférente 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 suis pas familier avec WPF (pas sûr s'il y a une solution prête à l'emploi pour votre question), mais peut-être que vous pouvez utiliser il.
En outre, il y a quelques commentaires sur son blog que dans certains cas, il ne parvient pas à évaluer la règle de validation correctement, mais il n'a jamais échoué pour moi.
Vous pourriez être intéressé par l'exemple d'application BookLibrary de Cadre D'Application WPF (WAF). Il fait exactement ce que vous demandez: en utilisant DataAnnotations dans WPF & Entity Framework.
J'ai eu la même question et a trouvé les idées suivantes:
- Modèle De Notification
- un port du contrôle DataForm de Silverlight vers WPF sur CodePlex
Utilisez une "classe buddy". Numéro 4 dans ce mode d'emploi .
J'ai écrit un validateur basé sur Contributor qui inclut un contributeur de validation DataAnnotation et vérifie également les liaisons brisées (où l'Utilisateur a entré un type incorrect)
Http://adammills.wordpress.com/2010/07/21/mvvm-validation-and-type-checking/
Dans. NET 4, Il existe un support de validation dans Entity-Framework utilisant cette extension, consultez: http://blogs.msdn.com/adonet/archive/2010/01/13/introducing-the-portable-extensible-metadata.aspx
Je ne suis pas sûr s'il utilise DataAnnotations tho.
Mise à JOUR
Je l'ai essayé avec VB.NET et cela n'a pas fonctionné, je pense qu'il ne supporte que les projets C#.