Announcements
Announcements copied to clipboard
[Breaking change]: Updated empty body detection in MVC Model Binding
Description
The mechanism to detect an empty request body
during the MVC Model Binding now uses the IHttpRequestBodyDetectionFeature.CanHaveBody
, that is currently implemented by the following behavior:
-
true
when:- It's an
HTTP/1.x
request with a non-zeroContent-Length
or aTransfer-Encoding: chunked
header. - It's an
HTTP/2
request that did not set theEND_STREAM
flag on the initial headers frame.
- It's an
-
false
when:- It's an
HTTP/1.x
request with noContent-Length
orTransfer-Encoding: chunked
header, or theContent-Length
is0
. - It's an
HTTP/1.x
request withConnection: Upgrade
(e.g. WebSockets). There is no HTTP request body for these requests and no data should be received until after the upgrade. - It's an
HTTP/2
request that setEND_STREAM
on the initial headers frame.
- It's an
Since the previous behavior was a simple validation of the Content-Length == 0
, in some scenarios when requests are not sending all needed HTTP information, could now be detected as empty request and report a failure to the client.
Version
7.0.0-preview3
Previous behavior
Before if you have a Controller's action that bind a parameter from body:
[HttpPost()]
public IActionResult Required([FromBody] TestClass value) => Ok(value);
And the client request does not include a Content-Length
header, eg.:
curl --request POST -k -i "[action]" -H "Content-Type: application/json"
This request will cause an internal exception during the body deserialization:
Eg.: When using the System.Text.Json
input formatter
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.'
Also, a response payload similar to this will be receive by the client:
{
"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."
]
}
}
New behavior
With the updated detection mechanism, the deserialization will not be trigger since an empty request body will be detected and only a validation
message will be reported back to the client. Eg.:
{
"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."
]
}
}
Type of breaking change
- [X] Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load/execute or different run-time behavior.
- [ ] Source incompatible: Source code may encounter a breaking change in behavior when targeting the new runtime/component/SDK, such as compile errors or different run-time behavior.
Reason for change
This change is an alignment with other parts of the framework that were already using the IHttpRequestBodyDetectionFeature.CanHaveBody
and also a fix to a reported issue dotnet/aspnetcore/issues/29570
Recommended action
No change is required, however, if you getting an unexpected behavior is recommended to review if your client's requests are sending the appropriated headers/information.
Affected APIs
MVC Action Controllers