Existe-t-il un moyen de valider l'utilisation de DataAnnotations dans WPF et Entity Framework?
Réponses
Trop de publicités?Vous pouvez utiliser le DataAnnotations.Classe de validation, comme décrit ici:
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);
}
}
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.
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.
J'ai eu la même question et trouvé les idées suivantes:
- Modèle de notification
- Un port du contrôle DataForm de Silverlight à WPF sur CodePlex
Utilisez une "classe de copain". Numéro 4 dans ce tutoriel .