Context
While reviewing PR #83 for #54/#73, we investigated how ASP.NET Core MVC avoids recursion-based validation issues when property getters or framework object graphs are problematic.
MVC generally does not catch exceptions from property getters during validation. Instead, it avoids traversing many risky child graphs through validation metadata:
ValidationEntry stores child model access lazily, so MVC can skip entries before invoking a property getter.
ValidationVisitor.VisitChildren checks metadata.PropertyValidationFilter?.ShouldValidateEntry(...) before evaluating entry.Model.
[ValidateNever] implements IPropertyValidationFilter; MVC has tests proving skipped properties are not accessed.
ModelMetadata.ValidateChildren can be set to false by metadata providers.
- MVC registers default
SuppressChildValidationMetadataProviders for framework/terminal types such as Type, Delegate, MethodInfo, MemberInfo, ParameterInfo, Assembly, Uri, CancellationToken, form-file types, and Stream.
- Newtonsoft MVC setup additionally suppresses child validation for
IJsonPatchDocument and JToken.
Relevant ASP.NET Core files observed:
src/Mvc/Mvc.Core/src/ModelBinding/Validation/ValidationVisitor.cs
src/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cs
src/Mvc/Mvc.Abstractions/src/ModelBinding/Validation/ValidationEntry.cs
src/Mvc/Mvc.Core/src/Infrastructure/MvcCoreMvcOptionsSetup.cs
src/Mvc/Mvc.Core/src/ModelBinding/SuppressChildValidationMetadataProvider.cs
src/Mvc/Mvc.NewtonsoftJson/src/DependencyInjection/NewtonsoftJsonMvcOptionsSetup.cs
Current MiniValidation behavior
PR #83 addresses the immediate crash reports by treating delegates, reflection types, and selected JSON/dynamic framework namespaces as terminal/non-validatable types. This is directionally similar to MVC's suppression approach and avoids broad getter-exception swallowing.
However, MiniValidation's suppression list is currently hardcoded inside TypeDetailsCache.IsNonValidatableType(...). MiniValidation has [SkipRecursion] for opt-out on model members, but it does not have an MVC-like configurable global mechanism for suppressing recursion into types owned by framework/library packages.
Follow-up idea
Consider adding an options/configuration mechanism for recursive validation suppression, similar in spirit to MVC's SuppressChildValidationMetadataProvider:
- Allow callers to configure types or predicates that should be treated as terminal for recursion.
- Seed the default list with MVC-aligned framework types where appropriate.
- Consider namespace/full-name based suppression for optional dependencies without taking package references, similar to MVC's XML full-type-name provider.
- Preserve
[SkipRecursion] as the per-member opt-out.
- Avoid broad catch-and-ignore behavior for arbitrary property getter exceptions.
Possible API shapes to explore:
MiniValidator.TryValidate(model, new MiniValidationOptions
{
SuppressChildValidationTypes = { typeof(Delegate), typeof(Uri) },
SuppressChildValidationTypeNames = { "Newtonsoft.Json.Linq.JToken" }
}, out var errors);
or static/global defaults if an options object would be too large a change.
Questions
- Should MiniValidation expose a configurable suppression list, or is a small built-in terminal-type list sufficient?
- Should MVC's default suppressed types be mirrored exactly, partially, or used only as inspiration?
- Can this be added without making the public API too option-heavy?
- Should this be part of a future 0.11.0 feature release or deferred beyond that?
Context
While reviewing PR #83 for #54/#73, we investigated how ASP.NET Core MVC avoids recursion-based validation issues when property getters or framework object graphs are problematic.
MVC generally does not catch exceptions from property getters during validation. Instead, it avoids traversing many risky child graphs through validation metadata:
ValidationEntrystores child model access lazily, so MVC can skip entries before invoking a property getter.ValidationVisitor.VisitChildrenchecksmetadata.PropertyValidationFilter?.ShouldValidateEntry(...)before evaluatingentry.Model.[ValidateNever]implementsIPropertyValidationFilter; MVC has tests proving skipped properties are not accessed.ModelMetadata.ValidateChildrencan be set tofalseby metadata providers.SuppressChildValidationMetadataProviders for framework/terminal types such asType,Delegate,MethodInfo,MemberInfo,ParameterInfo,Assembly,Uri,CancellationToken, form-file types, andStream.IJsonPatchDocumentandJToken.Relevant ASP.NET Core files observed:
src/Mvc/Mvc.Core/src/ModelBinding/Validation/ValidationVisitor.cssrc/Mvc/Mvc.Core/src/ModelBinding/Validation/DefaultComplexObjectValidationStrategy.cssrc/Mvc/Mvc.Abstractions/src/ModelBinding/Validation/ValidationEntry.cssrc/Mvc/Mvc.Core/src/Infrastructure/MvcCoreMvcOptionsSetup.cssrc/Mvc/Mvc.Core/src/ModelBinding/SuppressChildValidationMetadataProvider.cssrc/Mvc/Mvc.NewtonsoftJson/src/DependencyInjection/NewtonsoftJsonMvcOptionsSetup.csCurrent MiniValidation behavior
PR #83 addresses the immediate crash reports by treating delegates, reflection types, and selected JSON/dynamic framework namespaces as terminal/non-validatable types. This is directionally similar to MVC's suppression approach and avoids broad getter-exception swallowing.
However, MiniValidation's suppression list is currently hardcoded inside
TypeDetailsCache.IsNonValidatableType(...). MiniValidation has[SkipRecursion]for opt-out on model members, but it does not have an MVC-like configurable global mechanism for suppressing recursion into types owned by framework/library packages.Follow-up idea
Consider adding an options/configuration mechanism for recursive validation suppression, similar in spirit to MVC's
SuppressChildValidationMetadataProvider:[SkipRecursion]as the per-member opt-out.Possible API shapes to explore:
or static/global defaults if an options object would be too large a change.
Questions