Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EmptyBodyBehavior.Allow should allow a missing Content-Type #36466

Closed
BieleckiLtd opened this issue Sep 13, 2021 · 5 comments · Fixed by #38092
Closed

EmptyBodyBehavior.Allow should allow a missing Content-Type #36466

BieleckiLtd opened this issue Sep 13, 2021 · 5 comments · Fixed by #38092
Assignees
Labels
bug This issue describes a behavior which is not expected - a bug. feature-model-binding old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Milestone

Comments

@BieleckiLtd
Copy link

BieleckiLtd commented Sep 13, 2021

EmptyBodyBehavior.Allow allows a 0-length body, but does not work if the request does not have a Content-Type header. To make bodies truly optional, we need to expand the behavior of the switch to allow a missing Content-Type.

Original bug:

Describe the bug

This is either a bug or I'm using this new ASP.NET Core 5.0 feature wrong/API doc is not clear.

To Reproduce

  1. Create new ASP.NET Core Web API from the default template, VS2019, target Framework = .NET 5.0 (Current)

  2. Add below action at the end of the existing WeatherForecastController.cs:

[HttpPost("[action]")]
public async Task<IActionResult> MyAction([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] IEnumerable<int> elements = default)
{
    return Ok(elements);
}
  1. I am using Postman, my application is available at port 44349.
  2. I set Body as 'raw', body type JSON and body: [1,2]
  3. I send POST request to https://localhost:44349/WeatherForecast/MyAction
  4. SUCCESS, response is 200 body is [1,2]
  5. I clear request body (still 'raw', JSON)
  6. FAILURE, response is 415 Unsupported Media Type. I would expect 204 No Content
  7. I change Body as 'none'
  8. FAILURE, response is 415 Unsupported Media Type. I would expect 204 No Content

Exceptions (if any)

No exceptions, action is not being hit in point 8 and 10

Further technical details

  • ASP.NET Core version 5.0
  • dotnet --info
    .NET SDK (reflecting any global.json):
    Version: 5.0.301
    Commit: ef17233f86

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\5.0.301\

Host (useful for support):
Version: 5.0.7
Commit: 556582d964

.NET SDKs installed:
2.1.602 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
2.1.801 [C:\Program Files\dotnet\sdk]
2.2.401 [C:\Program Files\dotnet\sdk]
5.0.301 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

  • The IDE (VS / VS Code/ VS4Mac) VS2019 Pro (16.10.3)

Related

#30690

@rafikiassumani-msft rafikiassumani-msft added the old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels label Sep 13, 2021
@rafikiassumani-msft
Copy link
Contributor

@pranavkm any thoughts on this ?

@pranavkm
Copy link
Contributor

EmptyBodyBehavior operates at the formatter level - once a formatter is picked, it decides to allow an empty body. Picking a formatter requires a Content-Type and the absence of one would produce a 415. Perhaps that's what's happening here.

@BieleckiLtd
Copy link
Author

Is there any way to leverage this functionality then? If I was using HttpClient for example to call this action, I would have to newop dummy JsonContent for instance and attach with the body?

@BieleckiLtd
Copy link
Author

BieleckiLtd commented Sep 14, 2021

Is there any way to leverage this functionality then? If I was using HttpClient for example to call this action, I would have to newop dummy JsonContent for instance and attach with the body?

As per this SO answer: Just add content-type in your request header. Without the content-type:application/json will appear 415 when body is empty.

@pranavkm pranavkm reopened this Oct 6, 2021
@pranavkm pranavkm added the bug This issue describes a behavior which is not expected - a bug. label Oct 6, 2021
@pranavkm pranavkm changed the title [Question/Bug] EmptyBodyBehavior.Allow behavior EmptyBodyBehavior.Allow should allow a missing Content-Type Oct 6, 2021
@pranavkm
Copy link
Contributor

pranavkm commented Oct 6, 2021

A workaround until this is resolved might be to create a formatter that does not require a Content-Type. e.g.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class AllowEmptyBodyAttribute : Attribute
{

}

public class EmptyBodyFormatter : IInputFormatter
{
    public bool CanRead(InputFormatterContext context)
    {
        var endpoint = context.HttpContext.GetEndpoint();
        return endpoint?.Metadata.GetMetadata<AllowEmptyBodyAttribute>() is not null;
    }

    public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
    {
        return InputFormatterResult.NoValueAsync();
    }
}

[HttpPost]
[AllowEmptyBody]
public IActionResult Action(MyPoco? poco) { ... }

Note that this is using a different attribute to allow selection. MVC does not expose EmptyBodyBehavior via ModelMetadata, so we can't query that.

@captainsafia captainsafia added this to the .NET 7 Planning milestone Oct 7, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Dec 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue describes a behavior which is not expected - a bug. feature-model-binding old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants