I am using asp.net core 2.1, the source for StatusCodePagesMiddleware.cs
if (!statusCodeFeature.Enabled)
{
// Check if the feature is still available because other middleware (such as a web API written in MVC) could
// have disabled the feature to prevent HTML status code responses from showing up to an API client.
return;
}
appears to present the assumption that the API middleware disables the handler, however it does not. Is there a cleaner way to enable the middleware only for MVC requests without a call to app.UseWhen and checking the path string, or is this the best approach?
app.UseWhen(
context => !context.Request.Path.Value.StartsWith("/api", StringComparison.OrdinalIgnoreCase),
builder => builder.UseStatusCodePagesWithReExecute("/.../{0}"));
It's somewhat down to interpretation, but I'd say that comment is just suggesting that something could have disabled the feature, but not that anything actually does, by default.
I don't think there's anything obviously cleaner - what you have makes sense but another option would be to use a custom middleware that toggles the feature off. Here's what that might look like:
public void Configure(IApplicationBuilder app)
{
// ...
app.UseStatusCodePagesWithReExecute("/.../{0}");
app.Use(async (ctx, next) =>
{
if (ctx.Request.Path.Value.StartsWith("/api", StringComparison.OrdinalIgnoreCase))
{
var statusCodeFeature = ctx.Features.Get<IStatusCodePagesFeature>();
if (statusCodeFeature != null && statusCodeFeature.Enabled)
statusCodeFeature.Enabled = false;
}
await next();
});
// ...
app.UseMvc();
// ...
}
The right answer for me was to use plain UseStatusCodePagesWithReExecute in Startup.cs but vary the handling in the error controller. This allowed me to return plain text content for API errors but retain a friendly view for users.
Startup.cs
app.UseStatusCodePagesWithReExecute("/error/{0}");
Error controller:
[HttpGet("error/{statusCode:int}")]
public IActionResult Error(int statusCode)
{
var statusCodeFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
var exceptionDataFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
// ... Other logging and stuff
IActionResult actionResult;
if (statusCodeFeature == null || statusCodeFeature.OriginalPath.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase))
{
actionResult = Content($"The request could not be processed: {statusCode.ToString(CultureInfo.InvariantCulture)}");
}
else
{
ViewBag.StatusCode = statusCode;
actionResult = View();
}
return actionResult;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With