Anotaciones de datos: validación recursiva de un gráfico completo de objetos

Tengo un gráfico de objetos salpicado con atributos DataAnnotation, donde algunas propiedades de los objetos son clases que tienen atributos de validación, y así sucesivamente.

En el siguiente escenario:

public class Employee { [Required] public string Name { get; set; } [Required] public Address Address { get; set; } } public class Address { [Required] public string Line1 { get; set; } public string Line2 { get; set; } [Required] public string Town { get; set; } [Required] public string PostalCode { get; set; } } 

Si trato de validar la dirección de un Employee sin valor para PostalCode , entonces me gustaría (y espero) una excepción, pero no recibo ninguna. Así es como lo estoy haciendo:

 var employee = new Employee { Name = "Neil Barnwell", Address = new Address { Line1 = "My Road", Town = "My Town", PostalCode = "" // <- INVALID! } }; Validator.ValidateObject(employee, new ValidationContext(employee, null, null)); 

¿Qué otras opciones tengo con Validator que garantice que todas las propiedades se validen recursivamente ?

Muchas gracias de antemano.

Mi respuesta fue demasiado larga para ponerla aquí, así que la convertí en una publicación de blog 🙂

Validación recursiva con DataAnnotations

La solución le brinda una manera de lograr la validación recursiva utilizando el mismo método básico que está utilizando ahora.

Aquí hay una alternativa al enfoque de atributo de aceptación. Creo que esto atravesará el objeto-gráfico correctamente y validará todo.

 public bool TryValidateObjectRecursive(T obj, List results) { bool result = TryValidateObject(obj, results); var properties = obj.GetType().GetProperties().Where(prop => prop.CanRead && !prop.GetCustomAttributes(typeof(SkipRecursiveValidation), false).Any() && prop.GetIndexParameters().Length == 0).ToList(); foreach (var property in properties) { if (property.PropertyType == typeof(string) || property.PropertyType.IsValueType) continue; var value = obj.GetPropertyValue(property.Name); if (value == null) continue; var asEnumerable = value as IEnumerable; if (asEnumerable != null) { foreach (var enumObj in asEnumerable) { var nestedResults = new List(); if (!TryValidateObjectRecursive(enumObj, nestedResults)) { result = false; foreach (var validationResult in nestedResults) { PropertyInfo property1 = property; results.Add(new ValidationResult(validationResult.ErrorMessage, validationResult.MemberNames.Select(x => property1.Name + '.' + x))); } }; } } else { var nestedResults = new List(); if (!TryValidateObjectRecursive(value, nestedResults)) { result = false; foreach (var validationResult in nestedResults) { PropertyInfo property1 = property; results.Add(new ValidationResult(validationResult.ErrorMessage, validationResult.MemberNames.Select(x => property1.Name + '.' + x))); } } } } return result; } 

Código más actualizado: https://github.com/reustmd/DataAnnotationsValidatorRecursive

Paquete: https://www.nuget.org/packages/DataAnnotationsValidator/

Además, he actualizado esta solución para manejar gráficos cíclicos de objetos. Gracias por la respuesta.