Move back [FromBody] and [Required] to derived controllers #1506
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR moves back
[FromBody]
and[Required]
to derived controllers, reverting most of the previous PR (#1503). It turns out that ASP.NET ModelState doesn't take attributes on base parameters into account.As is often the case, there's more to it. The
ParameterInfo.GetCustomAttributes
method has always had the bug that it doesn't look at attributes on base methods, even withinherit: true
. To address that, without taking a breaking change,Attribute.GetCustomAttributes
was introduced, which properly takes base classes into account (but not interfaces). Aside from StackOverflow here and here, this isn't mentioned anywhere in the official docs (a remark about it was actually removed). Only a comment in the .NET runtime source code explains it:However, ASP.NET Core does not use the new method (and neither does Swashbuckle). Tests succeeded in the previous PR because most input validation is handled during JSON:API deserialization, before ModelState kicks in, combined with the fact we only run ModelState validation on POST/PATCH resource endpoints. While we can work around this for Swashbuckle, we can't know what other libraries are out there, possibly using the old broken method. Therefore it seems safest to have the attributes on the derived controller class (as it was). And not having them on the base class, for maximum flexibility for users deriving and tweaking things (same for routes).
QUALITY CHECKLIST