Skip to content

Preserve application/problem+json and application/problem+xml when using ProducesAttribute#66461

Open
Youssef1313 wants to merge 1 commit intomainfrom
dev/ygerges/39802
Open

Preserve application/problem+json and application/problem+xml when using ProducesAttribute#66461
Youssef1313 wants to merge 1 commit intomainfrom
dev/ygerges/39802

Conversation

@Youssef1313
Copy link
Copy Markdown
Member

Fixes #39802

What happens in this case is InferContentTypes is called with result.ContentTypes already having some content type (which might be application/json, for example, in case of [Produces(MediaTypeNames.Application.Json)]).

Previously we then added the application/problem+json and application/problem+xml to that list. However, DefaultOutputFormatterSelector.SelectFormatter will prefer application/json because it encounters it first.

This PR changes InferContentTypes to ensure that application/problem+json and application/problem+xml are added first to the list.

The test ExecuteAsync_ForProblemDetailsValue_UsesProblemDetailsXMLContentType_BasedOnAcceptHeader didn't originally capture the bug because:

  • It sets ObjectResult.ContentTypes to text/plain
  • InferContentTypes then adds application/problem+json and application/problem+xml to the end of the list.
  • However, because Accept header was set to application/xml, the test had the correct behavior and didn't capture the bug. Because the only content type that is compatible with Accept header is the correct application/problem+xml. The test was modified to parameterize the ObjectResult.ContentTypes. When the test input is application/xml, the bug would be captured by the test.
  • In addition, another test case is added, to ensure that we correctly consider Response.ContentType when we are dealing with ProblemDetails, in case no formatter can handle json or xml. This test would capture a bug that might happen if wasEmpty is moved after we added the ProblemJson and ProblemXml.

Copilot AI review requested due to automatic review settings April 24, 2026 15:00
@Youssef1313 Youssef1313 requested a review from a team as a code owner April 24, 2026 15:00
@github-actions github-actions Bot added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Apr 24, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts MVC’s ObjectResultExecutor content-type inference so application/problem+json / application/problem+xml are preferred for ProblemDetails, even when [Produces] has already populated ObjectResult.ContentTypes, fixing incorrect application/json selection during formatter negotiation (Issue #39802).

Changes:

  • Update InferContentTypes to insert problem media types at the start of ObjectResult.ContentTypes for ProblemDetails.
  • Expand/parameterize the existing XML negotiation test to catch the [Produces("application/xml")] regression.
  • Add a new test ensuring Response.ContentType is still considered as a fallback when no JSON/XML formatter is available.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs Reorders inferred ProblemDetails content types to prefer application/problem+json/+xml during formatter selection.
src/Mvc/Mvc.Core/test/Infrastructure/ObjectResultExecutorTest.cs Strengthens coverage for ProblemDetails content negotiation and adds fallback test case.

Comment thread src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs
Comment thread src/Mvc/Mvc.Core/src/Infrastructure/ObjectResultExecutor.cs
Comment thread src/Mvc/Mvc.Core/test/Infrastructure/ObjectResultExecutorTest.cs
@Aijazali777
Copy link
Copy Markdown

Donot know why checks failed.

@Youssef1313
Copy link
Copy Markdown
Member Author

@Aijazali777 I restarted it.

@mikekistler
Copy link
Copy Markdown
Contributor

This fix addresses the MVC controller path via ObjectResultExecutor.InferContentTypes, but the same problem exists in minimal APIs for generic TypedResults like Results.NotFound<ProblemDetails>(...), Results.BadRequest<ProblemDetails>(...), etc. — see #58574.

The minimal API path is actually simpler to fix. All generic typed results flow through HttpResultsHelper.WriteResultAsJsonAsync, which passes null for contentType, causing it to default to application/json. Meanwhile, the dedicated Results.Problem() and Results.ValidationProblem() already pass "application/problem+json" explicitly via ContentTypeConstants.ProblemDetailsContentType.

A similar fix could be applied in HttpResultsHelper.WriteResultAsJsonAsync (in src/Http/Http.Results/src/HttpResultsHelper.cs):

if (contentType is null && value is ProblemDetails)
{
    contentType = ContentTypeConstants.ProblemDetailsContentType; // "application/problem+json"
}

This would ensure that Results.NotFound<ProblemDetails>(...) returns application/problem+json at runtime, matching the behavior of Results.Problem() and aligning with the MVC fix in this PR.

This would partially address #58574 (the runtime content-type half — the OpenAPI metadata half would still need a separate change).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Media type application/problem+json still lost in combination with ProducesAttribute

4 participants