ASP.NET Core 2.0 Web API:如何在ActionFilterAttribute.OnResultExecuted中访问Model对象
如何在ActionFilterAttribute.OnResultExecuted()中获取POST请求的Model对象
这个问题我做ASP.NET Core项目时也碰到过,确实在OnResultExecuted方法里直接拿请求绑定后的Model有点棘手——因为到这个阶段,Action已经执行完成,默认的ResultExecutedContext里并没有直接保留Model实例。不过我们可以通过提前缓存Model的方式来解决,具体步骤如下:
解决方案:在Action执行后缓存Model,在Result执行后读取
核心思路是在OnActionExecuted(Action刚执行完的阶段)把绑定好的Model存到请求上下文的共享存储里,然后在OnResultExecuted里从这个存储中取出使用。
修改你的自定义筛选器代码
public sealed class MyCustomFilter : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext context) { // 定位Action中标记了[FromBody]的参数(也就是POST请求的Body数据) var bodyParam = context.ActionDescriptor.Parameters .FirstOrDefault(p => p.ParameterInfo.GetCustomAttributes(typeof(FromBodyAttribute), false).Any()); if (bodyParam != null && context.ActionArguments.TryGetValue(bodyParam.Name, out var model)) { // 将Model存入HttpContext.Items,它在整个请求生命周期内都可访问 context.HttpContext.Items["RequestBodyModel"] = model; } base.OnActionExecuted(context); } public override void OnResultExecuted(ResultExecutedContext context) { // 从HttpContext.Items中取出之前缓存的Model if (context.HttpContext.Items.TryGetValue("RequestBodyModel", out var model)) { // 转换为你的Model类型 var myModelList = model as List<MyModel>; if (myModelList != null) { // 这里就可以对myModelList执行你需要的操作了 } } base.OnResultExecuted(context); } public override void OnResultExecuting(ResultExecutingContext context) { base.OnResultExecuting(context); } }
代码说明
获取Model的方式:
context.ActionArguments是一个字典,保存了当前Action所有参数的键值对(键是参数名,值是绑定后的实例)。- 通过
ActionDescriptor.Parameters配合FromBodyAttribute来定位POST请求的Body参数,这种方式比硬编码参数名更通用,即使后续修改参数名称也不需要调整筛选器代码。
缓存Model的存储:
- 使用
HttpContext.Items来缓存Model,因为它是请求级别的存储,在整个请求的生命周期内(从请求开始到响应结束)都可以访问,刚好满足我们在OnResultExecuted中读取的需求。
- 使用
额外注意点:
- 如果Model绑定失败(比如请求Body格式错误),
context.Result会是BadRequestObjectResult,此时ActionArguments中对应的参数值可能为null,你可以根据业务需求添加对应的判断逻辑。
- 如果Model绑定失败(比如请求Body格式错误),
内容的提问来源于stack exchange,提问作者Farooq Hanif
相关产品推荐
相关产品推荐

