在ASP.NET Core 6 Web API异常筛选器中生成ProblemDetails
问题
ControllerBase类提供了便捷的Problem方法,可自动生成符合RFC7807标准的错误响应,仅需指定标题和状态码,其余值(如Type的URI引用)会自动填充。目前需设计全局异常筛选器,根据捕获的异常返回RFC7807格式的错误,但ProblemDetails类型无法自行生成所需值,且因错误可能在控制器创建前发生,无法使用ControllerBase.Problem方法。请问在ASP.NET Core 6中,能否在异常筛选器内自动生成ProblemDetails对象?
解决方案
在ASP.NET Core 6中完全可以在全局异常筛选器内自动生成符合RFC7807标准的ProblemDetails对象,核心是借助ProblemDetailsFactory服务——这正是ControllerBase.Problem方法底层依赖的组件,它能自动填充Type、Title、Status等标准字段,无需手动拼接。
具体实现步骤
注入ProblemDetailsFactory
在异常筛选器的构造函数中注入ProblemDetailsFactory,ASP.NET Core框架会自动提供默认实现:public class GlobalExceptionFilter : IExceptionFilter { private readonly ProblemDetailsFactory _problemDetailsFactory; public GlobalExceptionFilter(ProblemDetailsFactory problemDetailsFactory) { _problemDetailsFactory = problemDetailsFactory; } }在异常处理逻辑中生成ProblemDetails
捕获异常后,通过CreateProblemDetails方法生成标准格式的对象,可指定状态码、标题、详细描述等参数,未指定的字段(如Type的URI)会自动填充默认值:public void OnException(ExceptionContext context) { // 根据异常类型确定状态码,这里以500为例 var statusCode = StatusCodes.Status500InternalServerError; var problemDetails = _problemDetailsFactory.CreateProblemDetails( context.HttpContext, statusCode: statusCode, title: "服务器内部错误", detail: context.Exception.Message ); // 将ProblemDetails序列化为JSON并设置响应 context.Result = new ObjectResult(problemDetails) { StatusCode = statusCode, ContentTypes = { MediaTypeNames.Application.Json } }; context.ExceptionHandled = true; }注册全局异常筛选器
在Program.cs中添加筛选器到MVC服务配置:builder.Services.AddControllers(options => { options.Filters.Add<GlobalExceptionFilter>(); });
额外说明
- 对于控制器创建前发生的异常(如路由匹配失败、请求解析错误),全局异常筛选器可能无法捕获,此时可以结合
IApplicationBuilder.UseExceptionHandler中间件,同样在中间件内注入ProblemDetailsFactory来生成标准响应。 - 若需要自定义Type的URI或其他字段,可通过实现自定义的
ProblemDetailsFactory来覆盖默认行为,或在生成后手动修改ProblemDetails对象的属性。
内容的提问来源于stack exchange,提问作者lightning_missile
相关产品推荐
相关产品推荐

