-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Describe the bug
Even if you set AllowEmptyInputInBodyModelBinding = true it's basically impossible to have a nullable [FromBody] with no value that works across platforms because it still requires the content-length to be set, which browsers won't let you set, and won't set themselves on a null/empty or even "{}" body.
The standards say that if no body is passed you don't need to send the content-length header (for obvious reasons) thus the current implementation is not following standards and validating AllowEmptyInputInBodyModelBinding against the content-length header if and only if it is set when it should be if it is set to 0 or it doesn't exist.
To Reproduce
public async Task<ActionResult<IEnumerable<SubscriptionDto>>> ListSubscriptions(string? contactId = null, [FromBody] LoadCriteriaDto? criteria = null, CancellationToken cancellationToken = default)
This should allow a null criteria property to be received.
This does work with Android because Android allows setting the content-length header so you can set it to 0 if there is no body and still set the content-type = "application/json". (if you don't set the content-type you get a media type not supported even though the body is null which I believe is a separate bug because if the body is null, then the content-type should be null and it shouldn't be testing/validating it.)
As long as the Content-Length header is set on the request, and the body is null/empty then .net will accept the empty body. However as soon as the Content-Length header is not set but the body is null/empty then AllowEmptyInputInBodyModelBinding doesn't take effect and you get a validation error which is not correct and very problematic because all Chromium/Firefox browsers do not set the Content-Length header in this scenario AND you can't set it yourself because it's a protected header thus there is no way to actually send an empty body from a browser and have .NET accept it as an empty body.
Exceptions (if any)
Invaid json token
Proposed Solution:
- if AllowEmptyInputInBodyModelBinding = true, and the body is empty/null/{} and the content-length is not set/null then it should still work and not throw a validation error. (you can make this work by injecting middleware that if it sees no Content-length header, adds it to the request pipeline as a work around for now, but that isn't optimal)
- If the body is null, and the content-type header is not set, it shouldn't evaluate the media type because the deserializer is immaterial because there is no body and thus nothing to deserialize and combined with No. 1, should work fine with no content-type, no content-length, no body and AllowEmptyInputInBodyModelBinding = true.
- The inline FromBody attribute's ability to allow an empty body should also be updated to the same behavior.
Further technical details
- ASP.Net core 5.0.302
.NET SDK (reflecting any global.json):
Version: 5.0.302
Commit: c005824e35
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22000
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.302\
Host (useful for support):
Version: 6.0.0-preview.6.21352.12
Commit: 770d630b28
.NET SDKs installed:
5.0.302 [C:\Program Files\dotnet\sdk]
6.0.100-preview.6.21355.2 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.0-preview.6.21355.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.0-preview.6.21352.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.0-preview.6.21353.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
VS 2019