最近,我一直在尝试在我的 C# ASP.NET CORE 应用程序中实施处理异常的策略,但没有成功。该策略分为两部分:
第一个是让中间件单独负责处理我的应用程序可能抛出的给定自定义类型的异常。如果检测到,该中间件应该能够将其重定向回特定控制器的操作,该操作知道如何处理此类异常。
第二部分是处理中间件发送的异常的Controller。理想情况下,我想通过“HttpContext.Features.Get”方法检索异常(在控制器的端点内)。然而,尽管我尝试了,返回的功能还是返回为空;因此,我的控制器没有检索到异常(请参阅下面代码中的类型定义)。
我想指出,这个问题源于对在线找到的替代策略(例如在here和here中找到的策略)以及Microsoft文档本身的深入搜索。
感谢您抽出时间。如有任何帮助,我们将不胜感激。
public class ExceptionManagerController : AppController
{
public ExceptionManagerController() : base()
{
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> Index()
{
var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHttpContextFeature>();
var excecao = exceptionHandlerPathFeature?.Exception;
if ( excecao == null)
{
return RedirectToAction("Index", "Home");
}
else
{
var vm = new GlobalExceptionVM(excecao);
return View(vm);
}
}
}
public interface IExceptionHttpContextFeature
{
Exception Exception { get; }
}
public class ExceptionHttpContextFeature: IExceptionHttpContextFeature
{
public Exception Exception {get;}
public ExceptionHttpContextFeature()
{
}
public ExceptionHttpContextFeature(Exception exception)
{
this.Exception = exception;
}
}
public class GlobalExceptionHandler : IExceptionHandler
{
private ILogger<GlobalExceptionHandler> Logger;
public GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger)
{
Logger = logger;
}
public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{
if ( exception != null)
{
var originalBodyStream = httpContext.Response.Body;
Logger.LogError($"Erro na solicitação do usuário {httpContext.User.Identity.Name}. Error Message: {exception.Message}, Time of occurrence {DateTime.UtcNow}");
httpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
httpContext.Response.Redirect("/GestorDeExcecoes/Index");
httpContext.Features.Set<IExceptionHttpContextFeature>(new ExceptionHttpContextFeature(exception));
}
return true;
}
}
你尝试过这个吗:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/Error/Index", "?statusCode={0}");
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0
UseStatusCodePagesWithReExecute 中间件将重新执行 /Error/Index 操作,并将状态代码作为查询参数传递。