dotnet / dotnet/aspnetcore

[API Proposal]: Add SkipStatusCodePages property to ApiBehaviorOptions

Open
#45,369 6 comments 0 reactions 0 assignees View on GitHub
api-approved area-mvc feature-mvc-application-model
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

## Background and Motivation

When mixing MVC Controllers with Api Controllers in an application, there should be a global setting in [ApiBehaviorOptions](https://github.com/dotnet/aspnetcore/blob/44d89fa215aac65329c71038754063ea8c396e11/src/Mvc/Mvc.Core/src/ApiBehaviorOptions.cs) to turn off the [IStatusCodePagesFeature](https://github.com/dotnet/aspnetcore/blob/44d89fa215aac65329c71038754063ea8c396e11/src/Middleware/Diagnostics.Abstractions/src/IStatusCodePagesFeature.cs) for Api Controllers to avoid overriding the raw api response with an MVC view/html based status code page implementation.

## Proposed API

```diff
namespace Microsoft.AspNetCore.Mvc;

public class ApiBehaviorOptions : IEnumerable
{
+ public bool SkipStatusCodePages { get; set; }
}
```

## Usage Examples

```csharp
// Program.cs Minimal API

var builder = WebApplication.CreateBuilder(args);

// Register services

app.AddMvc().ConfigureApiBehaviorOptions(options =>
{
options.SkipStatusCodePages = true;
});

var app = builder.Build();

// Register middlewares

app.MapControllers();

await app.RunAsync();
```

## Alternative Designs

```
public static class SkipStatusCodePagesMetadataExtensions
{
public static IEndpointConventionBuilder SkipStatusCodePagesForApiControllers(this IEndpointConventionBuilder builder)
{
builder.Add(endpointBuilder =>
{
var apiControllerAttribute = endpointBuilder.Metadata.FirstOrDefault(m => m.GetType() == typeof(ApiControllerAttribute)) as ApiControllerAttribute;

if (apiControllerAttribute == null)
{
return;
}

endpointBuilder.Metadata.Add(new SkipStatusCodePagesMetadata());

endpointBuilder.FilterFactories.Add((context, next) =>
{
return async context =>
{
var statusCodeFeature = context.HttpContext.Features.Get();

if (statusCodeFeature != null)
{
// Turn off the StatusCodePages feature.
statusCodeFeature.Enabled = false;
}

return await next(context);
};
});
});

return builder;
}
}

// Marker metadata class
file class SkipStatusCodePagesMetadata : ISkipStatusCodePagesMetadata
{
}
```
```csharp
// Program.cs Minimal API

var builder = WebApplication.CreateBuilder(args);

// Register services

app.AddMvc();

var app = builder.Build();

// Register middlewares

app.MapControllers().SkipStatusCodePagesForApiControllers();

await app.RunAsync();
```

## Risks

There are no risks because the default value for `ApiBehaviorOptions.SkipStatusCodePages` will be `false` which is the current behavior.

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.