Fix ambiguous hidden-property lookup in validation#67455
Conversation
Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a reflection edge case in the validation pipeline where property lookup could throw AmbiguousMatchException when a derived type hides an inherited property with the same name. It aligns runtime property resolution with the declaring type information already emitted by the validation source generator.
Changes:
- Resolve properties in
ValidatablePropertyInfousingBindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnlyto avoid ambiguous matches from inherited members. - Add a regression test covering a hidden-property scenario and running both sync and async validation paths.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Validation/src/ValidatablePropertyInfo.cs | Switches reflection lookup to declared-only to prevent AmbiguousMatchException when properties are hidden in an inheritance chain. |
| src/Validation/test/Microsoft.Extensions.Validation.Tests/ValidatableTypeInfoTests.cs | Adds regression coverage for validating a derived type that hides a base property with the same name (sync + async paths). |
|
Will this change be backported to .NET 10? |
There was a problem hiding this comment.
We should have a test case that uses generics as in the original report (#64728). I remember from playing with the scenarios in the past that it changes the situation when the property has a generic type on level and non-generic on another. I understand that the BindingFlags.DeclaredOnly should implicitly avoid this as well but I would rather have it covered.
public class ODataQueryOptions
{
public virtual ETag IfMatch
{
...
}
}
public ODataQueryOptions<T> : ODataQueryOptions
{
public new ETag<T> IfMatch
{
get
{
return base.IfMatch as ETag<T>;
}
}|
@copilot Address #67455 (review). |
@mguinness It's not yet decided. |
Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
Addressed in commit |
oroztocil
left a comment
There was a problem hiding this comment.
There are also GetProperty calls emitted in https://github.com/dotnet/aspnetcore/blob/main/src/Validation/gen/Emitters/ValidationsGenerator.Emitter.cs#L157 and https://github.com/dotnet/aspnetcore/blob/main/src/Validation/gen/Emitters/ValidationsGenerator.Emitter.cs#L309
These should probably have the same flags.
|
@copilot Add a failing test covering the two |
Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
Done in I added a generator regression test that reproduces the hidden generic/non-generic property ambiguity in generated code ( |
Thanks for pointing out to these! Addressed in the last commit via Copilot. |
* Initial plan * Fix hidden property lookup during validation Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com> * Add generic hidden-property validation regression test Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com> * Fix emitted GetProperty lookup for hidden members Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
Fixes #64728