StatusCodePagesMiddleware doesn't intercept exceptions?

天涯浪子 提交于 2021-01-28 06:11:50

问题


For example, in the Index page:

public ActionResult OnGet()
{
    //return StatusCode(500);
    throw new Exception();
}

My Startup configuration:

public void Configure(IApplicationBuilder app)
{
    //app.UseStatusCodePagesWithReExecute("/Error", "?statusCode={0}");
    app.UseStatusCodePages();
    app.UseStaticFiles();
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

When the Index.OnGet() gets executed and throws the exception, the default 500 page of the browser is shown instead of the middleware page but works as expected when explicitly return StatusCode(500).

What I'm looking for is a generic way of handling errors: so I can use for example:

app.UseStatusCodePagesWithReExecute("/Error", "?statusCode={0}");

and in the error page, I can customize the HTML depending on the statusCode whether it's 4xx or 5xx.


回答1:


I'm usually using custom logging middleware like shown below that catches all exceptions and modifies the response status code.

public class LoggerMiddleware
{
    private readonly ILogger _log = ...

    private readonly RequestDelegate _next;

    public LoggerMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception ex)
        {
            _log.Warning(...);
            context.Response.Clear();
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        }
    }
}

Middleware extension

public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseLoggerMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<LoggerMiddleware>();
    }

    ...
}

In Startup#Configure, please make sure this is the first element in the custom middleware chain.

app.UseLoggerMiddleware();

Using app.UseStatusCodePagesWithReExecute("/Error", "?code={0}"); with error view like this:

@using Microsoft.AspNetCore.Http
@model ErrorViewModel
@{
    ViewData["Title"] = "Error";
}

<h1>Error.</h1>

@switch (Model.StatusCode)
{
    case StatusCodes.Status401Unauthorized:
    case StatusCodes.Status403Forbidden:
        <h2>No access to this resource.</h2>
        break;

    case StatusCodes.Status404NotFound:
        <h2>Could not find this resource</h2>
        break;

    default:
        <h2>An error occurred while processing your request.</h2>
        break;
}


来源:https://stackoverflow.com/questions/65636393/statuscodepagesmiddleware-doesnt-intercept-exceptions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!