如何使用操作和控制器名称获取ActionDescriptor

时间:2012-07-18 12:47:27

标签: asp.net-mvc asp.net-mvc-3

给定动作名称,控制器名称和HTTP动词(GET,POST等),是否可以检查动作是否具有特定动作过滤器属性(即装饰)?

请注意:操作和控制器不是当前操作和控制器,但可以是应用程序中的任何操作和控制器。

谢谢!

4 个答案:

答案 0 :(得分:4)

我已经回答了我自己的问题,这与此非常相似。

除了操作和控制器名称之外,您还需要http method(即GET,POST)才能获得正确的结果。

这是解决问题的代码片段:

var controllerFactory = ControllerBuilder.Current
    .GetControllerFactory();

var controllerContext = @this.ControllerContext;

var otherController = (ControllerBase)controllerFactory
    .CreateController(
        new RequestContext(controllerContext.HttpContext, new RouteData()),
        controllerName);

var controllerDescriptor = new ReflectedControllerDescriptor(
    otherController.GetType());

var controllerContext2 = new ControllerContext(
    new MockHttpContextWrapper(
        controllerContext.HttpContext.ApplicationInstance.Context,
        method),
    new RouteData(),
    otherController);

var actionDescriptor = controllerDescriptor
    .FindAction(controllerContext2, actionName);

答案 1 :(得分:1)

我遇到了类似的问题,我需要检查某个操作是否有自定义属性。

public static IEnumerable<MyCustomAttribute> GetAttributes(string controllerName, string actionName)
    {
        var types = Assembly.GetExecutingAssembly().GetTypes();
        var controllers = types.Where(t => (t.Name == controllerName));
        var action = controllers.SelectMany(type => type.GetMethods().Where(a => a.Name == actionName)).FirstOrDefault();
        return action.GetCustomAttributes<MyCustomAttribute>(true);
    }

归功于this SO answer

答案 2 :(得分:1)

万一有人编写单元测试,而controllerFactory却没有像Miguel Angelo的回答那样为他工作,这是我到目前为止提出的最好的结果:

var ctrl = // your controller instance of type T.
var controllerDescriptor = new ReflectedControllerDescriptor(ctrl.GetType());
var actionDescriptor = new ReflectedActionDescriptor(typeof(T).GetMethod(actionName), actionName, controllerDescriptor);

它没有找到控制器本身(它假定控制器),但是通常可以在编写测试时执行此操作...

答案 3 :(得分:0)

我不太清楚你想知道在哪个地方检查它。如果您是在OnActionExecutingOnActionExecuted中执行此操作。 ActionExecutedContext拥有财产ActionDescriptor。在那里,您可以找到IsDefined方法,该方法可以检查是否为此成员定义了指定属性类型的一个或多个实例。检查下面的代码示例:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    var hasAutorizeAttr = filterContext.ActionDescriptor
                            .IsDefined(typeof(AuthorizeAttribute), false);
    base.OnActionExecuted(filterContext);
}

编辑:好的,现在我收到您的问题了。看起来没有优雅的解决方案。如果您需要使用AjaxExtensions.BeginForm方法来检查其他操作,我只能看到一种方式 - 反思。但在我看来,在这种情况下你需要重新考虑你的架构。