J'ai un graphique d'objet parsemé d'attributs DataAnnotation, où certaines propriétés des objets sont des classes qui ont elles-mêmes des attributs de validation, etc.
Dans le scénario suivant:
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 j'essaie de valider un Employee
de Address
sans valeur pour PostalCode
, je voudrais (et j'attends) une exception, mais je n'en obtiens aucune. Voici comment je le fais:
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));
Quelles autres options ai-je avec Validator
qui garantiraient que toutes les propriétés sont validées récursivement?
Ma réponse est devenue trop longue pour être mise ici, alors je l'ai transformée en article de blog :)
Validation récursive à l'aide de DataAnnotations
La solution vous permet d'obtenir une validation récursive en utilisant la même méthode de base que vous utilisez actuellement.
Voici une alternative à l'approche d'attribut opt-in. Je crois que cela traversera correctement le graphique d'objet et validera tout.
public bool TryValidateObjectRecursive<T>(T obj, List<ValidationResult> 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<ValidationResult>();
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<ValidationResult>();
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;
}
Code le plus à jour: https://github.com/reustmd/DataAnnotationsValidatorRecursive
Paquet: https://www.nuget.org/packages/DataAnnotationsValidator/
De plus, j'ai mis à jour cette solution pour gérer les graphiques d'objets cycliques. Merci pour les commentaires.