aspnet / Announcements

Subscribe to this repo to be notified about major changes in ASP.NET Core and Entity Framework Core
Other
1.66k stars 80 forks source link

[Breaking change]: Updated empty body detection in MVC Model Binding #484

Open brunolins16 opened 2 years ago

brunolins16 commented 2 years ago

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:

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

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