MVC 对模型绑定中空主体的检测已更改

在 MVC 模型绑定期间检测空请求主体的机制现在使用 IHttpRequestBodyDetectionFeature.CanHaveBody。 此属性设置为:

  • true

    • 对于具有非零 Content-Length 请求头或 Transfer-Encoding: chunked 请求头的 HTTP/1.x 请求。
    • 对于初始标头框上未设置 END_STREAM 标志的 HTTP/2 请求。
  • false

    • 对于没有 Content-LengthTransfer-Encoding: chunked 请求头的 HTTP/1.x 请求,或者 Content-Length 请求标头是 0 的情况。
    • 对于具有 Connection: Upgrade 请求头的 HTTP/1.x 请求,如针对 WebSocket 的请求。 此类请求没有 HTTP 请求主体,因此在升级之前不应接收任何数据。
    • 对于初始标头框上设置 END_STREAM 标志的 HTTP/2 请求。

前面的行为对 Content-Length = 0 执行了最低程度的验证。 在某些情况下,当请求不包含所有必需的 HTTP 标头和标志时,现在可以将请求主体检测为具有空主体并向客户端报告失败。

引入的版本

ASP.NET Core 7.0

旧行为

如果控制器操作从请求主体绑定参数,同时客户端请求不包含 Content-Length 请求标头,则框架会在反序列化请求主体期间引发内部异常。 例如,基于 System.Text.Json 的输入格式化程序会引发异常,如下所示:

System.Text.Json.JsonException: 'The input does not contain any JSON tokens.
Expected the input to start with a valid JSON token, when isFinalBlock is true.
Path: $ | LineNumber: 0 | BytePositionInLine: 0.'

以下示例 JSON 显示了之前格式化为 ProblemDetails 响应的异常:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-34e98b5841b88bfb5476965efd9d9c8c-5bb16bc50dfbabb7-00",
  "errors": {
    "$": [
      "The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0."
    ],
    "value": [
      "The value field is required."
    ]
  }
}

新行为

如果 IHttpRequestBodyDetectionFeature.CanHaveBodyfalse,则不再尝试反序列化。 以下示例 ProblemDetails 响应显示了返回到客户端的错误消息如何指示请求主体为空:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "00-0f87920dc675fdfdf8d7638d3be66577-bd6bdbf32d21b714-00",
  "errors": {
    "": [
      "A non-empty request body is required."
    ],
    "value": [
      "The value field is required."
    ]
  }
}

中断性变更的类型

此更改会影响二进制兼容性。

更改原因

旨在与使用 IHttpRequestBodyDetectionFeature.CanHaveBody 的框架的其他部分保持一致以及修复可选 [FromBody] 模型绑定不起作用 (dotnet/aspnetcore #29570)

不需要进行任何更改。 但是,如果看到意外行为,请确保客户端请求发送相应的 HTTP 标头。

受影响的 API

MVC 控制器操作