Asp Core 3 - Как разрешить обнуляемый объект [FromBody] в методе контроллера - PullRequest
1 голос
/ 23 апреля 2020

Допустим, у меня есть простой контроллер с одним методом POST, который принимает объект из его тела. Однако наличие этого объекта должно быть необязательным в теле HTTP-запроса. Я попытался реализовать это поведение с помощью следующего кода

public class User
{
    public string Name { get; set; }
}

[ApiController]
[Route("[controller]")]
public class GreetingController : ControllerBase
{
    [HttpPost]
    public string SayHello([FromBody] User user = null)
    {
        return "Hello " + user?.Name;
    }
}

Если я сделаю запрос с объектом в теле, все работает нормально. Но с этой конфигурацией невозможно выполнить запрос POST с пустым телом. Если я создаю запрос без заголовка Content-Type (поскольку на самом деле нет содержимого), я получаю следующую ошибку:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
    "title": "Unsupported Media Type",
    "status": 415,
    "traceId": "|192e45d5-4bc216316f8d3966."
}

, если заголовок Content-Type имеет значение application/json, тогда ответ выглядит так: this:

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

Итак, как сделать объект необязательным в теле запроса? Это довольно распространенная проблема, и мне любопытно, есть ли простое решение для этого в ASP Core 3. Я не хочу читать объект из потока запросов и десериализовать его самостоятельно.

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020

Сейчас единственный способ - через глобальную опцию MvcOptions.AllowEmptyInputInBodyModelBinding. По умолчанию false, поэтому вам просто нужно сделать:

services.AddControllers(o =>
{
    o.AllowEmptyInputInBodyModelBinding = true;
});
0 голосов
/ 24 апреля 2020

Я не уверен относительно вашего окончательного намерения, но если вы не хотите выбирать тип контента, вы можете передать an empty json string.

В это время пользователь не пустой, а the content of it's field's value is null, и конечный результат тот же. Может быть, вы можете попробовать.

Вот процесс отладки с почтальоном:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...