-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Add generic variants of MVC attributes #47075
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
Conversation
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.
The new attributes are basically the same, e.g. [ModelMetadataType(typeof(DerivedModel))]
vs [ModelMetadataType<DerivedModel>]
- but it would be good to still have tests that using typeof(XXX)
works - realistically existing MVC code that uses the non-generic attributes will always be the majority of users. Are there still some left or have the tests all been updated to be generic?
I'd like a test of multiple attributes, e.g. [ModelMetadataType(typeof(DerivedModel))]
and [ModelMetadataType<DerivedModel>]
, and verify the error message is descriptive.
LGTM, modulo @JamesNK's suggestions. |
Yes, there are integration tests that still use the existing model (https://github.com/dotnet/aspnetcore/blob/fd211fb22e07f8b03e72d64b50117ba5d4ddf9a4/src/Mvc/test/Mvc.IntegrationTests/Models/SoftwareViewModel.cs). Also, I think we have decent coverage for it given that we call into the base constructor.
Done. Thoughts? |
@@ -287,6 +287,18 @@ public void GetAttributesForProperty_WithModelType_IncludesTypeAttributes() | |||
attribute => Assert.IsType<ClassValidator>(attribute)); | |||
} | |||
|
|||
[Fact] | |||
public void GetAttributeForProperty_WithModelType_HandlesMultipleAttributesOnType() |
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.
Great!
This covers ModelMetadataType. Are there other attributes that had AllowMultiple=false?
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.
ModelBinder
has it, but it's behavior is a little interesting. When constructing the model-binding context, we capture all the attributes on a type, including inherited ones (ref). When constructing the actual model binding context, we pick the attribute closest to the type were evaluating and use its properties to construct the context (ref).
So unlike the ModelMetadata
scenario, there isn't a place in code where we try to evaluate a single attribute on a type. We could modify the binding logic above to throw if there are multiple attributes on the same type. That would introduce a new exception in the code (although it's not possible to hit that exception without this current change).
Ditto the same situation for ProducesAttribute
. Although we only expect one attribute on a particular type, all the codepaths that consume it assume that attributes can be inherited and don't strictly expect a single attribute to be defined.
So we can throw exceptions at runtime that warn about multiple attributes on the same type but that feels a little heavy handed given the existing behavior for these attributes.
Thoughts?
Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime. |
98673d4
to
f5fdc0a
Compare
Bump! Reviving this for preview5. |
Stoked! The Great work team! |
Hi @marchy. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Closes #37767.
Since we have derived classes, the behavior of
GetCustomAttribute
is now different. I've updated the impacted codepaths that I could find.I didn't replace all instances of
ServiceFilter
andTypeFilter
in our tests because some of them don't reference types that actually implement theIFilterMetadata
interface (example). These tests aren't currently failing because they don't actually instantiate the factories.