dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.36k stars 9.99k forks source link

DataAnnotationsValidator throws AmbiguousMatchException when there are hidden members #27095

Open dhebbler opened 4 years ago

dhebbler commented 4 years ago

Describe the bug

We have a Blazor server side application that throws AmbiguousMatchException when editing values.

The DataAnnotationsValidator throws an AmbiguousMatchException when it encounters an object that has hidden members. This exception is thrown when you edit the input and the validator responds to the NotifyFieldChanged. The validator uses reflection to determine validation attributes. When the object being validated includes a hidden member, the GetProperty call without including specific binding flags sees both properties.

To Reproduce

This is a simple razor page. The model shown here is the minimum required to reproduce the issue. In our implementation this same OO pattern is inside a library that we do not have the ability to modify.

The exception will occur if you change the value of the InputNumber and tab away.

@using Microsoft.AspNetCore.Components.Forms 
@using Microsoft.AspNetCore.Components.Web 

<span>OrderID: @model.OrderID</span> 

<EditForm Model="model"> 
    <DataAnnotationsValidator></DataAnnotationsValidator> 
    <InputNumber @bind-Value="@model.OrderID"></InputNumber> 
    <ValidationMessage For="@(() => model.OrderID)"></ValidationMessage> 
    <button type="submit">Submit</button> 
</EditForm> 

@code{ 

    OrderClass model = new OrderClass() { OrderID = 555 }; 

    public class OrderBase 
    { 
        public object OrderID { get; set; } 
    } 

    public class OrderClass : OrderBase 
    { 
        [System.ComponentModel.DataAnnotations.Range(1, 100)] 
        public new int OrderID { get; set; } 
    } 
} 

Exceptions (if any)

Unhandled exception rendering component: Ambiguous match found.
System.Reflection.AmbiguousMatchException: Ambiguous match found.
at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
at System.Type.GetProperty(String name, BindingFlags bindingAttr)
at System.Type.GetProperty(String name)
at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.TryGetValidatableProperty(FieldIdentifier& fieldIdentifier, PropertyInfo& propertyInfo)
at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.ValidateField(EditContext editContext, ValidationMessageStore messages, FieldIdentifier& fieldIdentifier)
at Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.<>c_DisplayClass1_0.<AddDataAnnotationsValidation>b_1(Object sender, FieldChangedEventArgs eventArgs)
at Microsoft.AspNetCore.Components.Forms.EditContext.NotifyFieldChanged(FieldIdentifier& fieldIdentifier)

Further technical details

Runtime Environment: OS Name: Windows OS Version: 10.0.18363 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.100-rc.2.20479.15\

Host (useful for support): Version: 5.0.0-rc.2.20475.5 Commit: c5a3f49c88

.NET SDKs installed: 5.0.100-rc.2.20479.15 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0-rc.2.20475.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0-rc.2.20475.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.0-rc.2.20475.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]



- The IDE (VS / VS Code/ VS4Mac) you're running on, and it's version
Microsoft Visual Studio Enteprise 2019 Preview
Version 16.8.0 Preview 4.0 

- Sample Project
[BST_293680.zip](https://github.com/dotnet/aspnetcore/files/5417169/BST_293680.zip)
ghost commented 4 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

mkArtakMSFT commented 4 years ago

Thanks for contacting us. We will try to address this in the future. For now, try to remove the new keyword if you can when declaring the OrderId property - maybe by renaming to something else?

Simonl9l commented 3 years ago

@mkArtakMSFT - running into this issue. I have a DTO/Model that comes for another library. we inherit it and override the members with new and get/set reference back to the base such that we can add our own validation rules onto it - in this case [RegularExpression].

[RegularExpression(@"^[1-9]\d*$", ErrorMessage = "Minimum 1")]
public new int MyMember { get => base.MyMember; set => base.MyMember = value ; }

The difference in out case is that were overload the type type t be short so its more like this:

[RegularExpression(@"^[1-9]\d*$", ErrorMessage = "Minimum 1")]
public new int MyMember { get => base.MyMember; set => base.MyMember = (short)value ; }

This is done for all the member but breaks only where we overload the type member - if that inform the solution as a variable of the ambiguity to the original poster, but do get the error in the original posters scenario.

Any chance this gets addressed in an upcoming release given the current tagging? Any other work arounds...

ghost commented 9 months ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.