Asp 核心 3 - 如何在控制器方法中允许可为空的 [FromBody] object

Asp Core 3 - How to allow nullable [FromBody] object in controller method

假设我有一个简单的控制器,它有一个 POST 方法,该方法从其 body 中接受 object。但是,此 object 的存在在 HTTP 请求 body 中应该是可选的。我尝试使用以下代码实现此行为

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;
    }
}

如果我在 body 中使用 object 发出请求,一切正常。但是使用此配置,它无法发出空 body 的 POST 请求。如果我创建一个没有 Content-Type header 的请求(因为实际上没有内容),我会得到以下错误:

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

如果 Content-Type header 的值为 application/json 那么响应如下所示:

{
    "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."
        ]
    }
}

那么,如何在请求body中使object可选?这是一个很常见的问题,我很好奇 ASP Core 3 中是否有一个简单的解决方案。我不想从请求流中读取 object 并自行反序列化它。

现在,唯一的方法是通过全局选项,MvcOptions.AllowEmptyInputInBodyModelBinding。它默认为 false,因此您只需要做:

services.AddControllers(o =>
{
    o.AllowEmptyInputInBodyModelBinding = true;
});

我不确定你的最终意图,但如果你不想选择内容类型,你可以通过 an empty json string

此时用户不是空的,而是the content of it's field's value is null,最后的结果是一样的。或许你可以试试

下面是邮递员的调试过程:

现在有一种更简单的方法(自 5.0-preview7 起)

您现在可以通过配置名为 EmptyBodyBehavior

FromBodyAttribute 属性 来实现每个操作方法

示范:

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

感谢 LouraQ 在 github

上的 , which guided me towards the above answer