Media type application/problem+json still lost in combination with ProducesAttribute
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Describe the bug
This issue is the same as reported and resolved here: https://github.com/dotnet/aspnetcore/issues/19510
Having tested with the project that is the previous issue’s minimal repro (in .NET 6 instead of .NET core 3.1), I’ve found the same issue still persists.
That is, a controller with ProducesAttribute
set to application/json
will set the response header media-type
to application/json
when it’s returning a ProblemDetails
or ValidationProblemDetails
. It’s supposed to return application/problem+json
.
Expected Behavior
When the controller or framework returns a ProblemDetails
or ValidationProblemDetails
, the response header media type
should be application/problem+json
as per https://datatracker.ietf.org/doc/html/rfc7807#section-3
Steps To Reproduce
Minimalistic repro project: https://github.com/dsun1/ProblemMediaTypeIssue
Attribute a controller class or method with ProducesAttribute("application/json")
. If that controller returns a problem, or if the framework returns a validation problem, the response media type
will be application/json
instead of application/problem+json
.
Exceptions (if any)
No response
.NET Version
6.0.101
Anything else?
dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.101
Commit: ef49f6213a
Runtime Environment:
OS Name: Mac OS X
OS Version: 11.0
OS Platform: Darwin
RID: osx.10.16-x64
Base Path: /usr/local/share/dotnet/sdk/6.0.101/
Host (useful for support):
Version: 6.0.1
Commit: 3a25a7f1cc
.NET SDKs installed:
2.1.818 [/usr/local/share/dotnet/sdk]
3.1.416 [/usr/local/share/dotnet/sdk]
5.0.404 [/usr/local/share/dotnet/sdk]
6.0.101 [/usr/local/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.30 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.30 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.22 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.13 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.30 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.22 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.13 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Issue Analytics
- State:
- Created 2 years ago
- Reactions:8
- Comments:13 (6 by maintainers)
Top GitHub Comments
Same here. We need to be able to use both and get the correct media types.
So, the
ProducesAttribute
has anOnResultExecuting
hook that runs before the logic in theObjectResultExecutor
that was modified in the referenced PR runs. ThisOnResultExecuting
will clear outresult.ContentTypes
and replace it with the content types that are defined in theProducesAttribute
.https://github.com/dotnet/aspnetcore/blob/b21596afeb7412844ee5e19f6e5bef832c533c0f/src/Mvc/Mvc.Core/src/ProducesAttribute.cs#L91
https://github.com/dotnet/aspnetcore/blob/b21596afeb7412844ee5e19f6e5bef832c533c0f/src/Mvc/Mvc.Core/src/ProducesAttribute.cs#L101-L108
So, this is going to set
result.ContentTypes
to["application/problem+json", "application/json"]
. Now theInferContentType
method modified in the referenced PR effectively no-ops becauseresult.ContentTypes
is not empty and theresult.Value
is notProblemDetails
.https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs#L130-L142
I believe that the tests introduced in that PR didn’t catch the issue because they don’t account for the fact that the
ProducesAttribute
modifies the content types in this way.I think the fundamental right choice here is to modify the
ProducesAttribute
such that theOnResultExecuting
invocation no-ops under certain scenarios since that’s the root cause here.