如何从控制器获取所有操作名称

时间:2009-10-28 16:48:48

标签: asp.net-mvc

我如何编写代码以从asp.net MVC中的控制器获取所有动作名称?

我想自动列出控制器中的所有动作名称。

有谁知道怎么做?

非常感谢。

4 个答案:

答案 0 :(得分:8)

我一直在努力解决这个问题,我相信我已经提出了一个应该在大多数时间都可以工作的解决方案。它涉及为相关控制器获取ControllerDescriptor,然后检查ActionDescriptor返回的每个ControllerDescriptor.GetCanonicalActions()

我最终制作了一个动作,在我的控制器中返回了部分视图,但我认为弄清楚发生了什么是相当容易的,所以请随意使用代码并根据需要进行更改。

[ChildActionOnly]
public ActionResult Navigation()
{
    // List of links
    List<string> NavItems = new List<string>();

    // Get a descriptor of this controller
    ReflectedControllerDescriptor controllerDesc = new ReflectedControllerDescriptor(this.GetType());

    // Look at each action in the controller
    foreach (ActionDescriptor action in controllerDesc.GetCanonicalActions())
    {
        bool validAction = true;

        // Get any attributes (filters) on the action
        object[] attributes = action.GetCustomAttributes(false);

        // Look at each attribute
        foreach (object filter in attributes)
        {
            // Can we navigate to the action?
            if (filter is HttpPostAttribute || filter is ChildActionOnlyAttribute)
            {
                validAction = false;
                break;
            }
        }

        // Add the action to the list if it's "valid"
        if (validAction)
            NavItems.Add(action.ActionName);
    }

    return PartialView(NavItems);
}

可能有更多过滤器值得关注,但目前这符合我的需求。

答案 1 :(得分:3)

没有通用的解决方案,因为我可以编写一个派生自ActionNameSelectorAttribute的自定义属性,并使用任何自定义代码覆盖IsValidName,甚至可以将名称与随机GUID进行比较。在这种情况下,您无法知道属性将接受哪个操作名称。

如果您将解决方案仅限于考虑方法名称或内置ActionNameAttribute,那么您可以反思该类以获取返回ActionResult的公共方法的所有名称并检查是否他们有一个ActionNameAttribute,其Name属性会覆盖方法名称。

答案 2 :(得分:2)

您可以从:

开始
Type t = typeof(YourControllerType);
MethodInfo[] mi = t.GetMethods();
foreach (MethodInfo m in mi)
{
    if (m.IsPublic)
        if (typeof(ActionResult).IsAssignableFrom(m.ReturnParameter.ParameterType))
            methods = m.Name + Environment.NewLine + methods;
}

你必须更多地工作以满足你的需求。

答案 3 :(得分:0)

使用反射,将是一个非常好的起点。