UseExceptionHandler与UseStatusCodePagesWithRedirects

时间:2018-06-30 21:57:30

标签: c# asp.net-core

我一直在阅读有关ASP.NET Core中错误处理的信息,我遇到了以下两种方式:

  • UseExceptionHandler("/error")
  • UseStatusCodePagesWithRedirects("/error/{0}");

我想知道两者之间有什么区别?两者都重定向到错误页面,那么为什么要在另一个页面上使用?我什至看到有人同时使用它们。

1 个答案:

答案 0 :(得分:5)

您是正确的,两个中间件都提供错误页面。但是,它们有两个不同的用例,这将使在应用程序中同时实际使用两者非常有用。要了解差异,让我们看一下中间件在内部的实际工作方式。

这实际上是StatusCodePages middleware的作用:

// …
await _next(context);
// …

// 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;
}

var statusCodeContext = new StatusCodeContext(context, _options, _next);
await _options.HandleAsync(statusCodeContext);

它通过调用_next执行管道,并且在调用返回后(意味着所有以下中间件都已执行),它将检查当前响应:基本上,是否有错误状态代码或根本没有内容,它将执行状态代码页,并发出HTTP状态代码的信号。

另一方面,ExceptionHandler middleware的作用却大不相同:

try
{
    await _next(context);
}
catch (Exception ex)
{
    // …
    try
    {
        // …

        await _options.ExceptionHandler(context);

        // …
        return;
    }
    catch (Exception ex2)
    {
        // Suppress secondary exceptions, re-throw the original.
        _logger.ErrorHandlerException(ex2);
    }
    throw; // Re-throw the original if we couldn't handle it
}

这将尝试来调用中间件管道并捕获其可能产生的任何异常。然后,它将尝试运行已注册的异常处理程序(当设置路径时,该异常处理程序基本上意味着在内部调用该路径并返回其响应)。

所以总结一下:

  • StatusCodePages中间件将处理不成功的状态代码响应,并允许您指定例如自定义错误页面,例如“ 404未找到”。
  • ExceptionHandler中间件将在您的应用程序中捕获未处理的异常,并允许您为最终用户优雅地处理这些异常。

这两种中间件都有不同的用途,实际上它们的作用并不重叠。因此,将两者都包括在内通常是有意义的,除非您当然对这些问题的处理方式不同。例如一个API可能不需要状态代码页,但仍可能需要一个异常处理程序,该异常处理程序返回通用故障并正确记录所有内容。