#asp.net-core #controller
Вопрос:
Как передать необязательный (обнуляемый) параметр [FromBody] в ASP.NET Ядро (5.0)? Если я не отправлю тело в своем запросе, я получу ошибку 415 Неподдерживаемого типа носителя. Можно ли это настроить, и если да, то как это сделать на контроллере или действии, а не на уровне приложения? Я предполагаю, что это как-то связано с проверкой модели, но не уверен. Спасибо.
[HttpGet("[action]")]
public async Task<IActionResult> GetElementsAsync([FromBody] IEnumerable<int> elements = default)
{
var result = await dataService.GetData(elements);
return Ok(result);
}
ИЗМЕНИТЬ: Чтобы уточнить:
Это типичный сценарий, и он работает нормально:
Но прохождение пустого тела сразу же возвращает 415, даже не достигнув действия:
Ответ №1:
Просто добавьте тип содержимого в заголовок вашего запроса. Без content-type:application/json
воли появится 415
, когда тело опустеет.
Никаких изменений в вашем контроллере. Тест на моей стороне в порядке.
Я создал новую asp.net проект api core 5, и это мой контроллер:
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";
}
}
}
Ответ №2:
Вы можете найти решение здесь:
https://github.com/pranavkm/OptionalBodyBinding
Из этого выпуска на github:
https://github.com/dotnet/aspnetcore/issues/6878
И из .net Core 5 вы можете использовать этот:
public async Task<IActionResult> GetElementsAsync([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] IEnumerable<int> elements = default)
...
Также необходимо (из опыта Павла):
services.AddControllers(options =>{options.AllowEmptyInputInBodyModelBinding = true;})
Комментарии:
1. Требует ли это решение по-прежнему создания пользовательского фильтра? Я на .NET core 5.0 и просто добавляю (EmptyBodyBehavior = EmptyBodyBehavior. Разрешить) не изменил поведение.
2. Должно быть доступно без пользовательского фильтра. Проверьте глобальную настройку. Документ в GitHub и ms doc
3. Я попытался добавить аннотацию ссылочного типа с возможностью обнуления (
IEnumerable<int>?
— кто-то утверждал, что это сработало для них: github.com/dotnet/aspnetcore/issues/30690 ), настроить службыservices.AddControllers(options =>{options.AllowEmptyInputInBodyModelBinding = true;})
и отключить проверку моделиservices.Configure<ApiBehaviorOptions>(options => {options.SuppressModelStateInvalidFilter = true;});
, если ничего из этого не сработало :/4. Отличная работа, Павел !
5. Я думаю, что [от бога(пустотелое поведение = пустотелое поведение. Разрешить)] ожидает, что пользователь отправит пустое тело (как следует из названия), а не просто не отправит никакого тела. Разница между сообщением без тела и сообщением с пустым телом выглядит так: vs
curl --location --request POST 'https://localhost:44349/MyController/MyAction'
curl --location --request POST 'https://localhost:44349/MyController/MyAction' --data-raw ''