-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add validation for MetadataType attribute - Issue #46678 #51772
Conversation
Tagging subscribers to this area: @ajcvickers Issue DetailsFix for #46678 If MetadataType attribute is applied to a class the associated metadata class is now validated. To do this the System.ComponentModel.DataAnnotations.ValidationAttributeStore class was altered to check for a MetadataType attribute and add the properties from associated class to the store. Added tests to the System.ComponentModel.DataAnnotations.Validator for as many scenarios as I could think of.
|
@ajcvickers what is the process and timeline to get someone to review my PR? Also I can't get this to build due to the Helix failures that keep happening. Seems to be a common issue. Tagging in @lajones |
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
@ajcvickers @eerhardt @lajones when's the next time this can be reviewed ? |
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
var properties = t.GetProperties() | ||
.Where(prop => !prop.GetIndexParameters().Any()); | ||
|
||
foreach (PropertyInfo property in properties) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var properties = t.GetProperties() | |
.Where(prop => !prop.GetIndexParameters().Any()); | |
foreach (PropertyInfo property in properties) | |
{ | |
foreach (PropertyInfo property in t.GetProperties()) | |
{ | |
if (property.GetIndexParameters().Length == 0) | |
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should you also be filtering static
properties? GetProperties()
returns both instance and static properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've incorporated your suggested code. Is the reasoning of the style change to reduce memory and object iteration for performance reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eerhardt Re static
properties: Only public static properties will be processed. This is the same behavior as in .Net Framework. My branch finally got through all the pipelines, yay, progress. Thanks for all your help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eerhardt Kewl. No pressure but what's the usual turnaround for PR reviews like this one? Just setting my expectations 😎
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would hope the area owners would review this change. I'm just here reviewing because I was pinged on the issue, and was helping out on the "trim compatibility" parts of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Would it be appropriate for you to assign the review to ajcvickers?
@ajcvickers can we progress this? I and others have a lot of work with this as a dependency. |
Hi @eerhardt. Trying to progress this before .Net 6 is released 😂. I was wondering if this PR is setup/tagged correctly for the associated bug? Also any other settings, or advice to progress this would be appreciated. Thanks |
Sorry for being so slow on this. We are normally very hesitant to take changes in this area, especially where the behavior in .NET Framework and .NET Core would diverge. However, in this case we are bringing an existing .NET Framework behavior to .NET Core, which actually helps convergence. @bricelam I think you have some knowledge in this area. Does the change make sense to you? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @ajcvickers wrote, apologies for being so slow on this (I've been on vacation in the last three weeks).
I'm unfamiliar with this area, but the main question that comes to mind, is whether we shouldn't simply match the .NET Framework behavior here - more or less by copying the code across - rather than adding the new feature here (as @ajcvickers wrote this area is archived to a large extent). If I understand the situation correctly, this would mean that [MetadataType] wouldn't be respected for validation (it wasn't for .NET Framework), but TypeDescriptor.AddProviderTransparent would.
In any case, deferring to @bricelam (and @ajcvickers) who know this better.
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
+1 for using the .NET Framework code as reference. When all this code came into .NET Core, |
@bricelam . So I'm wondering what the next steps are. I'd like to keep this moving. Appreciate everyone's feedback, thanks. |
See #51772 (comment) |
/// </remarks> | ||
/// <param name="propertyDescriptor">The property descriptor whose attributes are needed.</param> | ||
/// <returns>A new <see cref="AttributeCollection"/> stripped of any attributes from the property's type.</returns> | ||
public static AttributeCollection GetExplicitAttributes(PropertyDescriptor propertyDescriptor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this method public? It seems to only be used by this class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 that would be a copy & paste fail from .NET Framework. Changed to internal. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(nit) Does it even need to be internal
? Why not private
?
...onentModel.Annotations/src/System/ComponentModel/DataAnnotations/ValidationAttributeStore.cs
Outdated
Show resolved
Hide resolved
...tem.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/ValidatorTests.cs
Show resolved
Hide resolved
Http3_MsQuic test failures are tracked in #56090. Should be fixed and merged shortly. Sorry for the inconvenience! |
Awesome it's approved! 😀. Thanks everyone. This is my first GitHub PR. Does it get auto-completed & merged or do I need to do something? |
@bricelam Can you take a final look at this when you get in today? @danmoseley @Pilchie Does this need to go through Ask Mode to get in for .NET 6? |
@ajcvickers there are no permissions (ever?) needed to fix anything in dotnet/runtime main. However on Aug 17 it will become a 7.0 branch so there would be ceremony if it wasn't in by then. |
@Xaeco It looks like |
Updated to honor class-level attributes. Squashed and rebased on top of |
Hello @bricelam! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
Looks like scenarios involving dynamically added properties will also be enabled by this PR. |
@bricelam thanks for making those changes. I started to but got interrupted and should've mentioned I was working on it. |
Thanks guys! |
And thank you, community, for making it happen! Things like this that bring parity with .NET Framework make everyone's migration go a little smoother. |
Glad to find this issue merged in .net6, can be ported to .net5? |
@Gambero81 this is very unlikely to be backported to .NET 5.0; patches are only done for serious bugs for which no workaround is available. |
If a MetadataType attribute is applied to a class the associated metadata class is now validated in .NET Core.
In .NET Framework 4.8 and older versions a similar behavior already exists if you use associate a type and handler like so:
TypeDescriptor.AddProviderTransparent( new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Person), typeof(PersonMetadata)), typeof(Person));
To do this the System.ComponentModel.DataAnnotations.ValidationAttributeStore class was altered to check for a MetadataType attribute. If found it inspects the associated class and merges any validation attributes with any from the class being validated.
Added tests to the System.ComponentModel.DataAnnotations.Validator for as many scenarios as I could think of.
Fixes #46678