diff --git a/src/MinimalValidation/MinimalValidation.cs b/src/MinimalValidation/MinimalValidation.cs index e47ebd1..10aa563 100644 --- a/src/MinimalValidation/MinimalValidation.cs +++ b/src/MinimalValidation/MinimalValidation.cs @@ -86,15 +86,15 @@ private static bool TryValidateImpl( foreach (var property in typeProperties) { - if (property.HasValidationAttribute) + if (property.HasValidationAttributes) { - var validationContext = new ValidationContext(target) { MemberName = property.PropertyInfo.Name }; + var validationContext = new ValidationContext(target) { MemberName = property.Name }; var validationResults = new List(); - var propertyValue = property.PropertyInfo.GetValue(target); - var propertyIsValid = Validator.TryValidateProperty(propertyValue, validationContext, validationResults); + var propertyValue = property.GetValue(target); + var propertyIsValid = Validator.TryValidateValue(propertyValue, validationContext, validationResults, property.ValidationAttributes); if (!propertyIsValid) { - ProcessValidationResults(property.PropertyInfo.Name, validationResults, errors, prefix); + ProcessValidationResults(property.Name, validationResults, errors, prefix); isValid = false; } } @@ -126,12 +126,12 @@ private static bool TryValidateImpl( if (property.IsEnumerable) { - var thePrefix = $"{prefix}{property.PropertyInfo.Name}"; + var thePrefix = $"{prefix}{property.Name}"; isValid = TryValidateEnumerable(propertyValue, recurse, errors, validatedObjects, thePrefix, currentDepth); } else { - var thePrefix = $"{prefix}{property.PropertyInfo.Name}."; + var thePrefix = $"{prefix}{property.Name}."; isValid = TryValidateImpl(propertyValue, recurse, errors, validatedObjects, thePrefix, currentDepth + 1); } } diff --git a/src/MinimalValidation/TypeDetailsCache.cs b/src/MinimalValidation/TypeDetailsCache.cs index 9c7025d..27b06a9 100644 --- a/src/MinimalValidation/TypeDetailsCache.cs +++ b/src/MinimalValidation/TypeDetailsCache.cs @@ -52,7 +52,8 @@ private void Visit(Type type, HashSet visited) continue; } - var hasValidationOnProperty = property.GetCustomAttributes().OfType().Any(); + var validationAttributes = property.GetCustomAttributes().OfType(); + var hasValidationOnProperty = validationAttributes.Any(); var hasSkipRecursionOnProperty = property.GetCustomAttributes().OfType().Any(); var enumerableType = GetEnumerableType(property.PropertyType); if (enumerableType != null) @@ -65,7 +66,7 @@ private void Visit(Type type, HashSet visited) if (type == property.PropertyType && !hasSkipRecursionOnProperty) { propertiesToValidate ??= new List(); - propertiesToValidate.Add(new (property, hasValidationOnProperty, true, enumerableType)); + propertiesToValidate.Add(new (property.Name, property, validationAttributes.ToArray(), true, enumerableType)); hasPropertiesOfOwnType = true; continue; } @@ -80,13 +81,14 @@ private void Visit(Type type, HashSet visited) if (recurse || hasValidationOnProperty) { propertiesToValidate ??= new List(); - propertiesToValidate.Add(new(property, hasValidationOnProperty, recurse, enumerableTypeHasProperties ? enumerableType : null)); + propertiesToValidate.Add(new(property.Name, property, validationAttributes.ToArray(), recurse, enumerableTypeHasProperties ? enumerableType : null)); hasValidatableProperties = true; } } if (hasPropertiesOfOwnType && propertiesToValidate != null) { + // Remove properties of same type if there's nothing to validate on them for (int i = propertiesToValidate.Count - 1; i >= 0; i--) { var property = propertiesToValidate[i]; @@ -124,10 +126,11 @@ private void Visit(Type type, HashSet visited) } } - internal record PropertyDetails(PropertyInfo PropertyInfo, bool HasValidationAttribute, bool Recurse, Type? EnumerableType) + internal record PropertyDetails(string Name, PropertyInfo PropertyInfo, ValidationAttribute[] ValidationAttributes, bool Recurse, Type? EnumerableType) { // TODO: Replace this with cached property getter (aka FastPropertyGetter) public object? GetValue(object target) => PropertyInfo.GetValue(target); public bool IsEnumerable => EnumerableType != null; + public bool HasValidationAttributes => ValidationAttributes.Length > 0; } }