aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Add SkipStatusCodePages flag to ApiBehaviorOptions

Open alienwareone opened this issue 2 years ago • 1 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

When mixing MVC Controllers with Api Controllers in an application, there should be a global setting to turn off the IStatusCodePagesFeature for Api Controllers to avoid overriding the raw api response with an MVC view/html based status code page implementation.

Describe the solution you'd like

Add the SkipStatusCodePages flag to the Microsoft.AspNetCore.Mvc.ApiBehaviorOptions class and add a new SkipStatusCodePagesConvention in ApiBehaviorApplicationModelProvider.

As a workaround I've extended the ApiControllerAttribute (implementation from SkipStatusCodePagesAttribute.

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class ApiControllerAttribute : Microsoft.AspNetCore.Mvc.ApiControllerAttribute, IResourceFilter, ISkipStatusCodePagesMetadata
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var statusCodeFeature = context.HttpContext.Features.Get<IStatusCodePagesFeature>();
        if (statusCodeFeature != null)
        {
            // Turn off the StatusCodePages feature.
            statusCodeFeature.Enabled = false;
        }
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
    }
}

Additional context

No response

alienwareone avatar Nov 24 '22 09:11 alienwareone

There is actually a cleaner "workaround" but a built-in global switch would be even cleaner ;-)

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<IStatusCodePagesFeature>();

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

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

        return builder;
    }
}

 // Marker metadata class
file class SkipStatusCodePagesMetadata : ISkipStatusCodePagesMetadata
{
}

alienwareone avatar Nov 24 '22 10:11 alienwareone

Triage: @alienwareone Would you be interested in filling out an API proposal for the the addition of a new property to to the ApiBehaviorOptions for this feature?

We can implement runtime behavior that would add the SkipStatusCodePageAttribute by default if the option was enabled.

You can view the API proposal template here. You are welcome to add a new comment to this issue with the API proposal template.

captainsafia avatar Nov 30 '22 00:11 captainsafia

Hi @alienwareone. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost avatar Nov 30 '22 00:11 ghost

Thanks! Closing this one and we'll track the other issue in our API review process.

captainsafia avatar Nov 30 '22 17:11 captainsafia