-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Add support for optional FromBody parameters #22634
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
7c8d4ea
to
d57ed85
Compare
I'll fix the source build. Just wanted to vet the design. |
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.
Changes look solid, I would need to look a bit more in depth to see if we are missing something since I'm not an expert in this area.
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.
Please change the IAllowEmptyInputInBodyModelBinding
definition.
More generally, I'm unsure whether this approach is better or worse than a new MvcOption.AllowEmptyInputInBodyModelBindingIfSet
option. We could implement that using ApiParameterDescription.DefaultValue
.
/// <remarks> | ||
/// When configured, takes precedence over <see cref="MvcOptions.AllowEmptyInputInBodyModelBinding"/>. | ||
/// </remarks> | ||
public bool AllowEmptyInputInBodyModelBinding |
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.
Suggest the property in IAllowEmptyInputInBodyModelBinding
should be non-nullable too. I don't see a use case for a tri-state property here.
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 was looking at being able to distinguish these two scenario:
.AddControllers(options => options.AllowEmptyInputInBodyModelBinding = true);
...
public IActionResult Post([FromBody(AllowEmptyInputInBodyModelBinding = false)] /* this API always require a body */ LoginModel model)
public IActionResult Post([FromBody] /* I'm ok with whatever was configured in MvcOptions */ CommentModel model)
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.
Then this property should be of type bool?
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.
Unfortunately attributes cannot have nullable properties that can be assigned to: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes#attribute-parameter-types. We could create an enum type to represent it. While it might be more correct to have an explicit distinction between fallback to 'system default' vs 'explicitly false', users don't really query the attribute so it seems like overkill.
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.
Perhaps overkill but the tri-state approach you want won't work as long as the only IAllowEmptyInputInBodyModelBinding
implementation has a non-nullable bool
.
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 interface IAllowEmptyInputInBodyModelBinding
is non-public. It's largely a result of weird layering - BindingInfo
is in Abstractions
, FromBody
is in Mvc.Core. We're free to assign it the shape we think works best.
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.
[FromBody(AllowEmpty = AllowEmptyBodyBehavior.Default)]
[FromBody(AllowEmpty = AllowEmptyBodyBehavior.Reject)]
[FromBody(AllowEmpty = AllowEmptyBodyBehavior.Allow)]
enum AllowEmptyBodyBehavior
{
Default,
Reject,
Allow
}
} | ||
|
||
_options = options; | ||
_formatters = formatters; | ||
_readerFactory = readerFactory.CreateReader; |
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 the reordering?
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.
Messed up. Will undo
Thanks both of you for the quick review. As @dougbu, relying on the default value of the parameters would have been super nice and most intuitive. I had hoped that's what we could do but there are a few issues with it that made me use this approach: a) We don't currently have access to parameter values in the binder \ binder factory. The best way I could think of resolving this is by adding b) Relying on default parameter values alone doesn't help solve it for properties. It would be nice to solve the problem for both kinds of bound types - parameters and properties. Using a property was something a user suggested - aspnet/Mvc#6920 (comment) and it has a fair number of upvotes so it doesn't seem entirely unappealing. |
@pranavkm got it, thanks for the explanation. That just leaves the |
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs
Outdated
Show resolved
Hide resolved
Hello @pranavkm! 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 (
|
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.
One teensy fixup…
{ | ||
/// <summary> | ||
/// Uses the framework default behavior for processing empty bodies. | ||
/// This is typically configured using <c>MvcOptions.AllowEmptyInputInBodyModelBinding</c> |
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.
End comment with another period
* Add support for optional FromBody parameters Fixes #6878 * Fixup nullable * Changes per API review
Fixes #6878