Implement runtime-based IValidatableTypeInfoResolver
implementation
#61220
Labels
area-minimal
Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc
feature-validation
Issues related to model validation in minimal and controller-based APIs
Milestone
Uh oh!
There was an error while loading. Please reload this page.
🚀 Goal
Provide a runtime implementation of
IValidatableTypeInfoResolver
so that minimal-API validation still works when the source-generator path is unavailable (e.g., dynamic compilation, IDEs without generators, or environments where generators are turned off).We already have a runtime implementation for parameter discovery (
RuntimeValidatableParameterInfoResolver
), but type discovery still falls back to the generated-code path. This issue tracks filling that gap.📚 Background & Current State
Compile-time story
The
Microsoft.AspNetCore.Http.ValidationsGenerator
source-generator analyzes user code and emits aGeneratedValidatableInfoResolver
that can resolve every validatable type/property via static look-ups (no reflection, very AOT-friendly).Runtime story
RuntimeValidatableParameterInfoResolver
already examines method parameters with reflection.TryGetValidatableTypeInfo
) is currently a stub that always returnsfalse
.Why we need a runtime fallback
🗺️ High-level Design
Type
, walking public instance properties recursively to build aValidatableTypeInfo
graph that mirrors the compile-time generator’s output.ConcurrentDictionary<Type, IValidatableInfo?>
to avoid repeated reflection.HashSet<Type>
during the walk to break infinite recursion (returnnull
for already-seen types).type.GetProperties()
overloads that allocate attribute arrays; useBindingFlags
filters and store only neededPropertyInfo
s.ConcurrentDictionary.GetOrAdd
instead oflock
.ValidationOptions.Resolvers
after generated resolvers so compile-time wins when present, but before any user-added fallback.🔨 Step-by-Step Tasks
Create the file
src/Http/Http.Abstractions/src/Validation/RuntimeValidatableTypeInfoResolver.cs
(namespace
Microsoft.AspNetCore.Http.Validation
).Scaffold the class
Implement the discovery walk
enum
, or one of the special cases handled byRuntimeValidatableParameterInfoResolver.IsClass
.[ValidationAttribute]
instances applied to the type.PropertyInfo
:IsEnumerable
→ implementsIEnumerable
but notstring
.IsNullable
→Nullable.GetUnderlyingType
!=null
or reference type.IsRequired
→ property has[Required]
or is a non-nullable reference type.HasValidatableType
→ recurse intoproperty.PropertyType
and check result.RuntimeValidatablePropertyInfo
object (mirrors the pattern in the parameter resolver).RuntimeValidatableTypeInfo
instance derived fromValidatableTypeInfo
.null
counts) before returning.Unit tests
Add tests under
src/Http/Http.Extensions/test/…
.Test cases:
[Required]
propertiesIsEnumerable == true
,HasValidatableType == true
Use
Validator.TryValidateObject
in assertions to validate behavior end-to-end.Wire-up
In
ServiceCollectionValidationExtensions.AddValidation
, register:Place it after generated resolver registration.
✅ Acceptance Criteria
🔗 Helpful Code References
src/Http/Http.Extensions/gen/Microsoft.AspNetCore.Http.ValidationsGenerator/*
src/Http/Http.Abstractions/src/Validation/RuntimeValidatableParameterInfoResolver.cs
The text was updated successfully, but these errors were encountered: