Aspnetcore: Optional [FromBody] Model Binding

Created on 20 Jan 2019  路  18Comments  路  Source: dotnet/aspnetcore

Is your feature request related to a problem? Please describe.

I am trying to use optional [FromBody] model binding on a per-endpoint basis.
Example:

        [HttpPost]
        public IActionResult Post([FromBody]SomeClass request = null)
        {
            return Ok();
        }

An empty request body results in the following being returned:

{
  "": [
    "A non-empty request body is required."
  ]
}

Describe the solution you'd like

For properties that have default value ie [FromBody] bool expandRelations = true to not be required in the body of the request.

Additional context

Similar issue here: https://github.com/aspnet/Mvc/issues/6920

area-mvc enhancement help wanted

Most helpful comment

I would also like to see a per-request option as mentioned by @hmvs here https://github.com/aspnet/Mvc/issues/6920#issuecomment-363754027

All 18 comments

Setting MvcOptions.AllowEmptyInputInBodyModelBinding should continue to work for this scenario. Are you seeing otherwise?

@pranavkm On a per-endpoint basis similar to the example, not globally for the entire web application.

@douglasg14b there isn't a feature to enable this on a per endpoint basis. One option might be to remove \ ignore specific that model validation error in your action.

I suppose this is a feature request then!

I can work around this for now, but it's a bit awkward.

I would also like to see a per-request option as mentioned by @hmvs here https://github.com/aspnet/Mvc/issues/6920#issuecomment-363754027

Thanks for contacting us, @douglasg14b.
We don't think we will get time to implement this feature.
However, this can be done by setting the MvcOptions.AllowEmptyInputInBodyModelBinding to true and implementing a custom ActionFilter which would validate the scenarios you care about explicitly.

Why close(+wontfix) this issue if it's just a matter of priority? There is no reasonably scoped workaround available and this problem won't go away in the foreseeable future.

@mkArtakMSFT Why close as wontfix if We don't think we will get time to implement this feature.? Sounds like this isn't a wontfix and is rather a low priority? Pentp's comment highlights the issue there.

If it's been decided that this will never be a feature in Asp.Net Core, that should probably be documented somewhere for clarification.

@pentp the reason is that keeping issues like this around just keeps accumulating our backlog without any good reason. If this is really something which community will benefit from a lot, we will hear similar feedback in the future again and we can reconsider then. There's just no point in accumulating backlog as it becomes unmanageable.

@douglasg14b I agree this is not really a "won't fix". It's a matter of priority and given our current priorities this doesn't and won't hit the bar in the near future.

Not to sound snide, but that sounds like your team needs an "On Hold" queue. It's what we use to manage items that won't be considered for a long time, or are blocked by a number of factors and need to sit for months.

There is no reasonably scoped workaround available

Why is the proposed solution of using the MvcOptions.AllowEmptyInputInBodyModelBinding setting + an action filter not workable?

By the way, here is a working sample @pranavkm has put together with the proposed alternative: https://github.com/pranavkm/OptionalBodyBinding

@douglasg14b if you're willing to send a PR for this, we'll happily consider it.

I have to agree, even if this is low priority I hate to see this simply be closed because that means it completely leaves the radar.

I thought the scoping of the two parts of the workaround would mismatch, but actually it looks fine. The actual filter probably needs some tuning to avoid excessive reflection.

My team experienced this same issue and we are also interested in a per-endpoint solution.
In the interim we are considering this work around which, in preliminary testing, has been able to handle an empty body without issue.

~~~~ c#
public class SomeClassModelBinder : IModelBinder
{
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
var stream = bindingContext.HttpContext.Request.Body;
string body;
using (var reader = new StreamReader(stream))
{
body = await reader.ReadToEndAsync();
}
var someClass = JsonConvert.DeserializeObject(body);

    bindingContext.Result = ModelBindingResult.Success(someClass);
}

}

[FromBody, ModelBinder(BinderType = typeof(SomeClassModelBinder))] SomeClass request,
~~~~

This is a 7th? revision of an MVC framework for .net and there's still workarounds required for common scenarios. This IMO violates the principle of least surprise. If object is declared nullable, doesn't that imply optional?

Another unfortunate side-effect is that it produces the ugly validation problem response:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "|ad6b5422-45a9ba2bb4b4f39b.",
  "errors": {
    "": [
      "A non-empty request body is required."
    ]
  }
}

This should be addressed in 5.0-preview7. FromBody attributes accepts a property that allows configuring individual parameters to be optional:

C# public IActionResult Post([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] MyModel model) ...

Was this page helpful?
0 / 5 - 0 ratings