dotnet / dotnet/aspnetcore

Enable Option to Use Content Negotiation for ProblemDetails

Open
#45,159 13 comments 4 reactions 0 assignees View on GitHub
api-needs-work area-minimal area-mvc
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

## Background and Motivation

The implementation of `DefaultProblemDetailsWriter` strictly enforces that `ProblemDetails` are only written if `Accept` is present and can be content negotiated. This is contrary to the HTTP specification. [RFC 7231 §5.3.2](https://www.rfc-editor.org/rfc/rfc7231#section-5.3.2) semantics for the `Accept` header states:

>_...disregard the header field by treating the response as if it is not subject to content negotiation._

The current behavior is very sensible as a default. It requires a client to understand they can get a `ProblemDetails` response; however, it is very common for API authors to not honor content negotiation for errors.

`DefaultProblemDetailsWriter` is `internal` and `sealed` with functionality that cannot be easily extended or customized. Ultimately, an API author simply wants to decide if content negotiation should take place for `ProblemDetails` and that shouldn't require customization when trivial configuration will suffice.

## Proposed API

The proposed API would be to extend `ProblemDetailsOptions` to include a property to determine whether content negotiation should be used. The default value will be `true`, which retains the current behavior. If a developer sets the value to `false`, the expectation is that content negotiation is skipped.

```diff
public class ProblemDetailsOptions
{
///
/// The operation that customizes the current instance.
///
public Action? CustomizeProblemDetails { get; set; }

+ ///
+ /// Gets or sets a value indicating whether to use HTTP content negotiation.
+ ///
+ /// True if the content negotiation is used; otherwise, false. The default value is true.
+ public bool UseContentNegotiation { get; set; } = true;
}
```

## Usage Examples

The default configuration where content negotiation is used. This is the same behavior as today.

```c#
builder.Services.AddProblemDetails();
```

A new configuration option which can instruct `IProblemDetailsWriter` implementations not to honor content negotiation.

```c#
builder.Services.AddProblemDetails(options => options.UseContentNegotiation = false);
```

## Risks

Nothing apparent. The default configuration and behavior would be retained.

## Additional Information

In accordance with [RFC 7231 §5.3.2](https://www.rfc-editor.org/rfc/rfc7231#section-5.3.2), if `Accept` is unspecified or is empty, then the value of `ProblemDetailsOptions.UseContentNegotiation` should be ignored and implied to be `false`. This behavior is being tracked in #45051.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.