one not length framework first code annotation .net wpf entity-framework validation data-annotations

.net - not - one to one relationship entity framework code first



¿Validar datos usando DataAnnotations con WPF y Entity Framework? (7)

¿Hay alguna forma de validar el uso de DataAnnotations en WPF y Entity Framework?


Creo que lo que falta en la respuesta de Craigs es cómo comprobar realmente si hay errores de validación. Este es un corredor de validación de DataAnnotation escrito por Steve Sanderson para aquellos que quieran ejecutar la verificación de validación en la capa deferente y luego en la presentación ( http://blog.codeville.net/category/xval/ , el código está en el proyecto de ejemplo):

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); }

No estoy familiarizado con WPF (no estoy seguro si hay alguna solución lista para usar), pero tal vez pueda usarla.

Además, hay algunos comentarios en su blog que en algunos casos no evalúa correctamente la regla de validación, pero nunca falló para mí.



Es posible que le interese la aplicación de ejemplo BookLibrary del WPF Application Framework (WAF) . Hace exactamente lo que está pidiendo: utilizar DataAnnotations en WPF y Entity Framework.



Puede usar la clase DataAnnotations.Validator, como se describe aquí:

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

Pero si está utilizando una clase de "amigo" para los metadatos, debe registrar ese hecho antes de validar, como se describe aquí:

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);

[Agregué lo siguiente para responder al comentario de Shimmy]

Escribí un método genérico para implementar la lógica anterior, para que cualquier objeto pueda llamarlo:

// 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; }

En cada objeto que necesita validarse, agrego una llamada a este método:

[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); } }