Skip to content

Fix ambiguous hidden-property lookup in validation#67455

Merged
Youssef1313 merged 4 commits into
mainfrom
copilot/fix-ambiguous-match-exception
Jun 30, 2026
Merged

Fix ambiguous hidden-property lookup in validation#67455
Youssef1313 merged 4 commits into
mainfrom
copilot/fix-ambiguous-match-exception

Conversation

Copilot AI commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #64728

Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix ambiguous match exception using .AddValidation() Jun 29, 2026
Copilot AI requested a review from Youssef1313 June 29, 2026 10:08
@Youssef1313 Youssef1313 marked this pull request as ready for review June 29, 2026 13:19
Copilot AI review requested due to automatic review settings June 29, 2026 13:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ValidatablePropertyInfo using BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly to 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).
@mguinness

Copy link
Copy Markdown

Will this change be backported to .NET 10?

@oroztocil oroztocil left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>;
        }
}
@Youssef1313

Copy link
Copy Markdown
Member
@Youssef1313

Copy link
Copy Markdown
Member

Will this change be backported to .NET 10?

@mguinness It's not yet decided.

Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>

Copilot AI commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Address #67455 (review).

Addressed in commit cf4a5df5. I added a regression test that covers the generic/non-generic hidden IfMatch property scenario (sync + async) to match the original issue shape.

Copilot AI requested a review from Youssef1313 June 29, 2026 15:01

@oroztocil oroztocil left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Youssef1313

Copy link
Copy Markdown
Member

@copilot Add a failing test covering the two GetProperty calls in the generated code, and then change it to use the same BindingFlags as already done ValidatablePropertyInfo, and ensure that test passes afterwards.

Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>

Copilot AI commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Add a failing test covering the two GetProperty calls in the generated code, and then change it to use the same BindingFlags as already done ValidatablePropertyInfo, and ensure that test ...

Done in 03e7cd35.

I added a generator regression test that reproduces the hidden generic/non-generic property ambiguity in generated code (PropertyDisplayName_WithResourceType_OnHiddenGenericProperty), then updated both emitted GetProperty call sites to use BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly. The new test fails before the emitter change and passes after it.

@Youssef1313

Copy link
Copy Markdown
Member

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.

Thanks for pointing out to these! Addressed in the last commit via Copilot.

@Youssef1313 Youssef1313 requested a review from oroztocil June 30, 2026 08:29

@oroztocil oroztocil left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@Youssef1313 Youssef1313 merged commit cda719f into main Jun 30, 2026
25 checks passed
@Youssef1313 Youssef1313 deleted the copilot/fix-ambiguous-match-exception branch June 30, 2026 10:17
javiercn pushed a commit that referenced this pull request Jun 30, 2026
* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants