我的startup.cs文件中有:
if (env.IsDevelopment()) {
app.UseExceptionHandler("/api/error/error-local-development");
}
else {
app.UseExceptionHandler("/api/error/error");
}
但是当
throw new Exception()
在控制器操作中时,永远不会调用错误控制器方法。
[Route("api/error")]
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
public class ErrorController : OwnBaseController
{
public ErrorController(IApplicationUserService applicationUserService, ILogger<ErrorController> logger, IDiagnosticContext diagnosticContext) : base(applicationUserService, logger, diagnosticContext)
{
}
[Route("error")]
public IActionResult Error()
{
return Problem();
}
[Route("error-local-development")]
public IActionResult ErrorLocalDevelopment([FromServices] IWebHostEnvironment webHostEnvironment)
{
var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
return Problem(
detail: context.Error.StackTrace,
title: context.Error.Message);
}
}
为什么这不起作用?
这可能看起来很奇怪,但顺序确实很重要。
UseExceptionHandler
和 UseRouting
都在底层注册中间件。
最先注册的将是最外层的中间件。因此,如果内部之一抛出异常,外部可以捕获并处理它。
MSDN对此有一些警告,例如:
如果指定了应用程序内的端点,请为端点创建 MVC 视图或 Razor 页面。确保
放置在UseStatusCodePagesWithReExecute
之前,以便可以将请求重新路由到状态页面。UseRouting
是添加到管道中的第一个中间件组件。因此,异常处理程序中间件会捕获后续调用中发生的任何异常。UseExceptionHandler
这对我没有帮助,所以我改变了这个
app.UseExceptionHandler("Home/Error");
到此
app.UseExceptionHandler("/Error");
aldo 在操作上添加了属性路由
[Route("/Error")]
public IActionResult Error()
对我来说,这是路由名称与 usEExceptionHandler 不同:
我有
[Route("/errors")]
public IActionResult Error()
在我的程序.cs中:
app.UseExceptionHandler("/error");
两个名称必须相同才能正常工作
在我的例子中,我将异常处理程序设置为在
UseEndpoints
之前调用。如果它出现在 UseEndpoints
之后,则处理程序永远不会被调用。
var app = builder.Build();
app.UseCors();
app.UseRouting();
app.UseAuthorization();
// should be called before UseEndpoints else the exception handler wont be called
app.UseExceptionHandler();
app.UseEndpoints(endpoints => endpoints.MapControllers());
app.MapControllers();
app.Run();