La detección de MVC de un cuerpo vacío en el enlace de modelos ha cambiado

El mecanismo para detectar un cuerpo de solicitud vacío durante el enlace de modelos de MVC ahora usa IHttpRequestBodyDetectionFeature.CanHaveBody. Esta propiedad se establece en:

  • true:

    • En las solicitudes de HTTP/1.x con un encabezado de solicitud Content-Length distinto de cero o un encabezado de solicitud Transfer-Encoding: chunked.
    • En las solicitudes de HTTP/2 que no establecen la marca END_STREAM en el marco del encabezado inicial.
  • false:

    • En las solicitudes de HTTP/1.x sin encabezados de solicitud Content-Length o Transfer-Encoding: chunked, o si el encabezado de solicitud Content-Length es 0.
    • En las solicitudes de HTTP/1.x con un encabezado de solicitud Connection: Upgrade, como las solicitudes de WebSockets. No hay ningún cuerpo de solicitud HTTP en estas solicitudes, por lo que no se deberían recibir datos hasta después de la actualización.
    • En las solicitudes de HTTP/2 que establecen la marca END_STREAM en el marco del encabezado inicial.

El comportamiento anterior realizaba una validación mínima de Content-Length = 0. En algunos escenarios, si las solicitudes no incluyen todos los encabezados HTTP y marcas necesarios, ahora se puede detectar que los cuerpos de solicitud tienen un cuerpo vacío y notificar un error al cliente.

Versión introducida

ASP.NET Core 7.0

Comportamiento anterior

Si una acción de controlador enlaza un parámetro del cuerpo de la solicitud y la solicitud cliente no incluye un encabezado de solicitud Content-Length, el marco inicia una excepción interna durante la deserialización del cuerpo de la solicitud. Por ejemplo, el formateador de entrada basado en System.Text.Json inicia una excepción similar a la siguiente:

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.'

En el siguiente ejemplo JSON se muestra la excepción anterior con formato de respuesta 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."
    ]
  }
}

Comportamiento nuevo

La deserialización ya no se intenta si IHttpRequestBodyDetectionFeature.CanHaveBody es false. En la respuesta de ejemplo ProblemDetails siguiente se muestra cómo el mensaje de error devuelto a los clientes indica que el cuerpo de la solicitud está vacío:

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

Tipo de cambio importante

Este cambio afecta a la compatibilidad binaria.

Motivo del cambio

Alinearse con otras partes del marco que usan IHttpRequestBodyDetectionFeature.CanHaveBody y corregir Optional [FromBody] Model Binding is not working (dotnet/aspnetcore #29570).

No es preciso realizar cambios. Pero si observa un comportamiento inesperado, asegúrese de que las solicitudes cliente envíen los encabezados HTTP adecuados.

API afectadas

Acciones del controlador de MVC