.NET 6中ExceptionFilterAttribute无法返回异常详情的问题
.NET 6异常过滤器导致请求中止的问题修复
问题分析
你的代码里存在几个关键问题,直接导致了Postman请求中止:
async void误用:ASP.NET Core中过滤器的异步方法不能用async void,这种写法会让异步操作脱离框架上下文管理,请求可能被提前终止,这是核心原因。- ContentType拼写错误:
"appication/json"少了字母'l',应为"application/json",错误的响应类型会导致客户端无法正确识别响应。 - 未标记异常已处理:没有设置
context.ExceptionHandled = true;,框架会继续处理未标记的异常,可能覆盖你的响应或中断请求流程。 - 占位符代码未完善:
var info = { }只是占位,实际需要将错误信息序列化为合法的JSON字符串才能正常返回。 - 不必要的Singleton注册:如果是直接在控制器上用
[TestFilter]特性,不需要注册为单例——特性会被实例化到控制器,单例注册反而可能引发线程安全问题。
修复后的代码
异常过滤器代码
public class TestFilterAttribute : ExceptionFilterAttribute { public override async Task OnExceptionAsync(ExceptionContext context) { // 构造错误信息对象 var errorInfo = new { Message = "请求处理发生异常", ExceptionDetail = context.Exception.Message, StatusCode = 400 }; // 序列化为JSON字符串 var jsonContent = System.Text.Json.JsonSerializer.Serialize(errorInfo); // 设置正确的响应类型和状态码 context.HttpContext.Response.ContentType = "application/json"; context.HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; // 写入响应内容 await context.HttpContext.Response.WriteAsync(jsonContent); // 标记异常已处理,阻止框架后续处理逻辑 context.ExceptionHandled = true; } }
注册调整
如果过滤器不需要依赖注入服务,直接删除services.AddSingleton<TestFilterAttribute>();——特性会在控制器上被直接实例化。如果需要注入服务,改为以下方式注册:
services.AddControllers(options => { // 可选:全局注册,作用于所有控制器 options.Filters.Add<TestFilterAttribute>(); }); // 若要保留特性标记+依赖注入,注册为Scoped(更符合Web请求生命周期) services.AddScoped<TestFilterAttribute>();
验证示例
在控制器上保留[TestFilter]特性,抛出测试异常:
[ApiController] [Route("api/test")] [TestFilter] public class TestController : ControllerBase { [HttpGet] public IActionResult Get() { throw new Exception("测试异常触发"); } }
此时Postman会正确返回JSON格式的错误响应,状态码400,不会再出现请求中止的提示。
内容的提问来源于stack exchange,提问作者super cool
相关产品推荐
相关产品推荐

