你是对的,两个中间件都提供了错误页面。然而,它们有两个不同的用例,这使得在应用程序中同时使用这两个用例非常有用。为了理解这些差异,我们来看看中间件的内部实际工作原理。
这本质上就是StatusCodePages 中间件 https://github.com/aspnet/Diagnostics/blob/2.1.1/src/Microsoft.AspNetCore.Diagnostics/StatusCodePage/StatusCodePagesMiddleware.cs does:
// …
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 状态代码。
The 异常处理中间件 https://github.com/aspnet/Diagnostics/blob/2.1.1/src/Microsoft.AspNetCore.Diagnostics/ExceptionHandler/ExceptionHandlerMiddleware.cs另一方面做了一些非常不同的事情:
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
}
这会try调用中间件管道并捕获它可能产生的任何异常。然后,它将尝试运行已注册的异常处理程序(设置路径时基本上意味着在内部调用该路径并返回其响应)。
总结一下:
- The StatusCodePages 中间件将处理不成功的情况状态码响应并允许您指定例如自定义错误页面,例如 404 Not Found。
- The 异常处理中间件另一方面会抓住未处理的异常在您的应用程序中,并允许您为最终用户优雅地处理这些问题。
两个中间件都有不同的用途,实际上它们的功能并不重叠。因此,将两者都包含在内通常是有意义的,当然,除非您以不同的方式处理这些问题;例如API 可能不需要状态代码页,但可能仍然需要一个异常处理程序来返回一般故障并正确记录所有内容。