MVC 对模型绑定中空主体的检测已更改
在 MVC 模型绑定期间检测空请求主体的机制现在使用 IHttpRequestBodyDetectionFeature.CanHaveBody。 此属性设置为:
true
:- 对于具有非零
Content-Length
请求头或Transfer-Encoding: chunked
请求头的HTTP/1.x
请求。 - 对于初始标头框上未设置
END_STREAM
标志的HTTP/2
请求。
- 对于具有非零
false
:- 对于没有
Content-Length
或Transfer-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.CanHaveBody 为 false
,则不再尝试反序列化。 以下示例 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 控制器操作