asp.net-core - ASP.NET Core 3 中的全局异常处理程序中间件
问题描述
上下文:我正在尝试找到一种方法来在我的 ASP.NET Core 3.0 Webapi 中添加一个全局异常处理程序中间件,该中间件可以捕获任何未处理的异常,记录它们并返回一个 ProblemDetails 响应。
这是我到目前为止在我的 Startup.cs 中得到的:(仅包括相关代码)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseExceptionHandler(new ExceptionHandlerOptions
{
ExceptionHandler = ProblemDetailsExceptionHandler
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
}
private async Task ProblemDetailsExceptionHandler(HttpContext context)
{
var requestServiceProvider = context.RequestServices;
var problemDetailsFactory = requestServiceProvider?.GetRequiredService<ProblemDetailsFactory>();
if (problemDetailsFactory == null) return;
if (context.Response.HasStarted)
{
// Log
return;
}
var problemDetails = problemDetailsFactory.CreateProblemDetails(context,
StatusCodes.Status500InternalServerError,
detail: "An error occurred");
context.Response.Headers.Add("Content-type", new StringValues("application/problem+json"));
await context.Response.WriteAsync(JsonSerializer.Serialize(problemDetails), Encoding.UTF8);
}
我所追求的:
- 如何访问异常对象以记录详细信息?
- 在我的异常处理程序委托 (ProblemDetailsExceptionHandler) 中,我是否需要检查响应是否已开始?
- 我还想捕获 404 并返回 ProblemDetails 响应。我怎样才能做到这一点?
解决方案
您可以使用自定义异常过滤器属性,如下所示
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
// if you want to do something special with specific exceptions type
if (context.Exception is TypeOfException)
{
// do something custom
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
context.Result = new JsonResult(
((ValidationException)context.Exception).Failures);
return;
}
var code = HttpStatusCode.InternalServerError;
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.StatusCode = (int)code;
context.Result = new JsonResult(new
{
error = new[] { context.Exception.Message },
stackTrace = context.Exception.StackTrace
});
}
}
然后注册进去Startup.cs
services.AddControllersWithViews(options => options.Filters.Add(typeof(CustomExceptionFilterAttribute)))
推荐阅读
- node.js - 如何从 get 方法中的 cors 禁用选项方法
- python - 使用 Symfit 进行全局拟合:数据集的类型结构
- kotlin - Kotlin-Native cinterop 从 C 更新 Struc 字段
- scala - AnalysisException:在数据架构中发现重复的列:`hour`、`eventTime`
- clickhouse - 将具有动态更改架构的事件数据流式传输到 ClickHouse
- laravel - laravel 无法访问关系属性
- python - Python多处理函数卡在一个带有while循环的函数中
- java - Android 照片上的 EXIF 方向字段为空
- angular - Angular 表单在使用 ng-zorro 初始化时未显示错误
- python - 如何在具有轮廓的 Numpy 2D 数组中找到形状?