为什么异常会重定向到不同的页面?

Tra*_*man 5 c# asp.net-core-mvc asp.net-core

我的应用程序正在运行ASP.NET Core RC2,我对状态代码和异常处理程序中间件如何工作感到困惑.

我的应用程序配置了以下中间件.

app.UseStatusCodePagesWithReExecute("/Error/Status/{0}");
app.UseExceptionHandler("/Error/ServerError");
Run Code Online (Sandbox Code Playgroud)

控制器处理它应返回的视图:

[HttpGet]
public IActionResult Status(int id)
{
    switch (id)
    {
        case 404:
            return View("404");
        case 400:
            return View("400");
        case 500:
            return View("500");
        default:
            return View("501");
    }
}

[HttpGet]
public IActionResult ServerError()
{
    return View();
}
Run Code Online (Sandbox Code Playgroud)

当我导航到一个未知的URL时,它将404 page从Status动作返回预期的.

当我导航到抛出异常的操作时,它将导航到状态操作/Error/ServerError而不是导航500 page.

public IActionResult ThrowException()
{
    throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)

如果我导航到返回的操作,StatusCodeResult(500);将返回500 pageStatus操作.

[HttpGet]
public IActionResult Error500()
{
    return new StatusCodeResult(500);
}
Run Code Online (Sandbox Code Playgroud)

令我困惑的是,控制台显示两个结果都返回500 (Internal Server Error)但是根据它们的返回方式,它们将导航到基于中间件的不同页面.

在此输入图像描述

为什么是这样?

Kir*_*lla 4

当我导航到引发异常的操作时,它将导航到 /Error/ServerError 而不是状态操作中的 500 页面。

这是预期的,因为 ExcetionHandlerMiddleware 处理未处理的异常,并且还注册了after状态代码页中间件,因此在响应发出时首先执行。我相信,即使您重新排序这些中间件,您也不会看到行为上的差异,因为状态代码页中间件会在传出的 HttpResponse 实例上查找状态代码,并且在出现未处理的异常的情况下,可能不会设置该状态代码。

更新: 回复评论。您可以执行如下操作:

[HttpGet]
public IActionResult ServerError()
{
    var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
    if (exceptionHandlerFeature != null)
    {
         var exception = exceptionHandlerFeature.Error;

         //TODO: log the exception
    }
    return View("500");
}
Run Code Online (Sandbox Code Playgroud)