如何从当前请求中获取ActionContext?
如何从当前请求中获取有效的ActionContext
一、解决ActionContextAccessor返回null的问题
你遇到的null问题,核心是获取时机不对:ActionContext是在请求处理过程中(路由匹配完成后)才会被赋值,不能在启动阶段(比如Program.cs直接调用)获取,必须在请求上下文已存在的环节使用。
正确用法示例:
- 在控制器中注入使用
public class DemoController : ControllerBase { private readonly IActionContextAccessor _actionContextAccessor; // 构造函数注入IActionContextAccessor public DemoController(IActionContextAccessor actionContextAccessor) { _actionContextAccessor = actionContextAccessor; } [HttpGet] public IActionResult Test() { var actionContext = _actionContextAccessor.ActionContext; // 这里actionContext不为null,可以正常获取描述符和特性 return Ok(); } }
- 在中间件中使用(需在路由之后)
必须确保中间件在UseRouting()之后、UseEndpoints()之前注册,因为路由匹配后ActionContext才会被设置:
app.UseRouting(); // 路由匹配后的中间件 app.Use(async (context, next) => { var actionContextAccessor = context.RequestServices.GetRequiredService<IActionContextAccessor>(); var actionContext = actionContextAccessor.ActionContext; if (actionContext != null) { // 执行你的逻辑,比如获取特性 } await next(); }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
二、自行创建ActionContext时获取有效特性
你手动new的ActionDescriptor是空对象,自然拿不到特性。需要通过IActionDescriptorCollectionProvider获取当前请求对应的真实ActionDescriptor:
// 获取服务 var descriptorProvider = HttpContext.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>(); var routeData = HttpContext.GetRouteData(); // 从已注册的ActionDescriptor集合中匹配当前请求的控制器和操作 var targetDescriptor = descriptorProvider.ActionDescriptors.Items .FirstOrDefault(ad => ad.RouteValues["controller"] == routeData.Values["controller"]?.ToString() && ad.RouteValues["action"] == routeData.Values["action"]?.ToString()); if (targetDescriptor != null) { var actionContext = new ActionContext(HttpContext, routeData, targetDescriptor); // 现在可以正常获取特性 var httpAttributes = targetDescriptor.GetAttributes<HttpMethodAttribute>().Result; var routeAttribute = targetDescriptor.GetAttributes<RouteAttribute>().Result.FirstOrDefault(); string entity = routeAttribute?.Name; }
三、更简单的替代方案
如果是在控制器方法或过滤器中,无需额外注入,直接获取:
- 控制器方法直接参数注入
[HttpGet] public IActionResult Test(ActionContext actionContext) { // 直接使用actionContext return Ok(); }
- 过滤器中通过上下文获取
public class CustomFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { var actionContext = context.ActionContext; // 处理逻辑 } public void OnActionExecuted(ActionExecutedContext context) { // ... } }
内容的提问来源于stack exchange,提问作者Formula12
相关产品推荐
相关产品推荐

