如何为视图文件中的异常配置自定义错误页面?

use*_*181 2 asp.net-core-mvc asp.net-core asp.net-core-2.0

我们正在使用UseStatusCodePagesWithReExecute中与设置一个简单的自定义中间件组合Response.StatusCode500,成功地将用户引导至我们的自定义错误页上发生在MVC控制器例外.

但是,对于在razor/cshtml视图中发生的异常,UseStatusCodePagesWithReExecute不会将用户发送到我们的错误页面(尽管我们的自定义中间件会检测到这些异常Invoke()).

我们也尝试使用异常过滤器,但它只捕获控制器操作的异常,而不是视图.

如果异常来自视图,有没有办法将用户发送到我们的错误页面?

Cod*_*ler 6

StatusCodePagesMiddleware在执行底层中间件后,通过UseStatusCodePagesWithReExecute扩展调用添加了以下检查:

// Do nothing if a response body has already been provided.
if (context.Response.HasStarted
    || context.Response.StatusCode < 400
    || context.Response.StatusCode >= 600
    || context.Response.ContentLength.HasValue
    || !string.IsNullOrEmpty(context.Response.ContentType))
{
    return;
}
Run Code Online (Sandbox Code Playgroud)

当视图开始渲染,MVC中间件填补Response.ContentTypetext/html价值.这就是为什么上面的检查返回true和带状态代码页的请求不会被重新执行的原因.

修复很简单.在处理异常的中间件中,调用Clear()方法Response:

public async Task InvokeAsync(HttpContext context)
{
    try
    {
        await _next(context);
    }
    catch (Exception)
    {
        context.Response.Clear();
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
    }
}
Run Code Online (Sandbox Code Playgroud)

GitHub上的示例项目