Reputation: 1297
How do I pass optional (nullable) [FromBody] parameter in ASP.NET Core (5.0)? If I don't send body in my request I get 415 Unsupported Media Type error. Can this be configured and if so, how to do it on a controller or action, rather than an app level? I presume it has to do something with model validation, but not sure. Thanks.
[HttpGet("[action]")]
public async Task<IActionResult> GetElementsAsync([FromBody] IEnumerable<int> elements = default)
{
var result = await dataService.GetData(elements);
return Ok(result);
}
EDIT: To clarify:
This is typical scenario and it works normally:
But passing empty body is returning 415 right away without even reaching action:
Upvotes: 18
Views: 26589
Reputation: 5297
add this line to configuration
services.AddControllers().ConfigureApiBehaviorOptions(options => { options.SuppressModelStateInvalidFilter = true; });
Upvotes: 0
Reputation: 151
As per filters execution flow diagram https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-3.1 ResourceFilters
are executed before model binding so you can make a hack and set content-type in order model binder to not crash so you can accept request with no body and content-type header passed from client
public class MediaTypeResourceFilterAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
context.HttpContext.Request.ContentType ??= "application/json";
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
Upvotes: 0
Reputation: 2340
I will address some points that were not mentioned here.
https://stackoverflow.com/a/65813534/2531209
But I would say this is an overkill
Content-Type: application/json
in your request header you will get "Body cannot be empty" (Tested on .NET 6) and only then @Nicola answer comes in handy.From my tests it looks like modifications to the controller are not needed and only FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)
is enough with nullable type as parameter.
Content-Type: application/json
with a body of {}
. This will bypasses all of those errors, but this is not the most optimal solutions for public API'sUpvotes: 2
Reputation: 183
With ASP.NET Core 3.1, I could allow nullable
optional parameters by implementing Nicola's suggestion:
services.AddControllers(options =>{options.AllowEmptyInputInBodyModelBinding = true;})
Upvotes: 2
Reputation: 15971
Just add content-type in your request header. Without the content-type:application/json
will appear 415
when body is empty.
No changes to your controller. Test in my side is ok.
I created a new asp.net core 5 api project and this is my controller:
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace WebApi_net5.Controllers
{
public class HomeController : ControllerBase
{
[HttpGet("[action]")]
public string GetElementsAsync([FromBody] IEnumerable<int> elements = default)
{
return "value";
}
}
}
Upvotes: 11
Reputation: 2800
You can find a solution here:
https://github.com/pranavkm/OptionalBodyBinding
From this issue on github:
https://github.com/dotnet/aspnetcore/issues/6878
And from .net Core 5 you can use this one:
public async Task<IActionResult> GetElementsAsync([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] IEnumerable<int> elements = default)
...
Also needed (from Pawel experience):
services.AddControllers(options =>{options.AllowEmptyInputInBodyModelBinding = true;})
Upvotes: 14