我们将UseStatusCodePagesWithReExecute
与将Response.StatusCode
设置为500
的简单自定义中间件结合使用,以成功将用户发送到我们的自定义错误页面,了解mvc控制器中发生的异常。
但是,对于razor / cshtml视图中发生的异常,UseStatusCodePagesWithReExecute
不会将用户发送到我们的错误页面(尽管我们的自定义中间件确实会在Invoke()
中检测到这些异常)。
我们也尝试使用异常过滤器,但它只捕获控制器操作的异常,而不是视图。
如果异常来自视图,是否有办法将用户发送到我们的错误页面?
答案 0 :(得分:5)
StatusCodePagesMiddleware
扩展名has the following check添加了 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;
}
当View的渲染开始时,MVC中间件将Response.ContentType
填入text/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;
}
}