.NET Core 2.0中如何从IActionFilter获取真实Http状态码?
解决ASP.NET Core 2.0过滤器中无法获取真实状态码的问题
我之前也碰到过这个一模一样的坑!在OnActionExecuted过滤器里直接拿controller.Response.StatusCode总是返回200,核心原因是时机不对:当Action抛出未处理的异常时,ASP.NET Core的异常处理中间件是在过滤器执行之后才会把状态码改成500的,所以这个阶段Response还保持着默认的200状态。另外,直接从Controller的Response对象读取也不是最可靠的方式,得换个思路从ActionExecutedContext本身的属性入手。
下面是修正后的解决方案:
核心思路
分三种场景判断真实状态码:
- 存在未处理异常时,直接标记为500(也可根据异常类型自定义)
- Action返回带状态码的结果时,直接从结果对象读取
- 正常执行时,从HttpContext的Response获取
修正后的代码实现
public void OnActionExecuted(ActionExecutedContext context) { try { int statusCode; // 场景1:Action抛出了未被处理的异常,此时Response状态码还未被更新 if (context.Exception != null && !context.ExceptionHandled) { statusCode = StatusCodes.Status500InternalServerError; // 可根据异常类型自定义状态码,比如: // if (context.Exception is NotFoundException) statusCode = StatusCodes.Status404NotFound; } // 场景2:Action返回了带状态码的结果(如StatusCodeResult、ObjectResult等) else if (context.Result is IStatusCodeActionResult statusCodeResult) { statusCode = statusCodeResult.StatusCode ?? context.HttpContext.Response.StatusCode; } // 场景3:Action正常执行,直接读取Response状态码 else { statusCode = context.HttpContext.Response.StatusCode; } // 后续使用statusCode进行业务处理 var controller = context.Controller as APIServiceBase; // ...你的其他逻辑代码 } catch { // 异常捕获逻辑 } }
关键细节说明
context.ExceptionHandled:如果这个值为true,说明异常已经被Action内部或其他过滤器处理过,此时Response的状态码可能已经被正确设置了。IStatusCodeActionResult:这是ASP.NET Core中所有带状态码返回结果的统一接口,覆盖了NotFoundResult、BadRequestResult、ObjectResult等常见类型,从这里读取状态码比从Response拿更及时准确。
内容的提问来源于stack exchange,提问作者blue
相关产品推荐
相关产品推荐

