【问题标题】:Get all Area, Controller and Action as a tree以树的形式获取所有区域、控制器和动作
【发布时间】:2016-02-05 13:47:38
【问题描述】:

我需要将所有已注册为列表的区域及其所有控制器作为子列表以及相同的操作。像这样:

AdminArea
   HomeController
     Index
     Add
     ...
   OtherController
   ...
AnotherArea
   HomeController
      Index
      ...
...

我已经检查了this 问题的答案,以及这个one,但它们不是我想要的。 第一个返回所有已注册的路由,第二个一次返回所有控制器。

更新

好的,通过下面的代码我可以得到所有的区域,通过第二个问题的答案我可以得到所有的控制器,但我无法弄清楚每个控制器属于哪个区域。

var areaNames = RouteTable.Routes.OfType<Route>()
            .Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area"))
            .Select(r => r.DataTokens["area"]).ToList()
            .Distinct().ToList();

【问题讨论】:

  • 为什么这些问题不是您想要的?帮助我们了解为什么它们不适合您。
  • 我检查了两个链接,它们一起拥有实现您所要求的所有信息。做一些工作,如果你遇到困难,展示你做了什么,然后社区可能会尝试帮助你而不是为你做这些工作。

标签: c# asp.net-mvc-5


【解决方案1】:

所以这就是我想出的,这正是我想要的。 我希望它会有所帮助。

    public virtual ActionResult Index()
    {
        var list = GetSubClasses<Controller>();

        // Get all controllers with their actions
        var getAllcontrollers = (from item in list
            let name = item.Name
            where !item.Name.StartsWith("T4MVC_") // I'm using T4MVC
            select new MyController()
            {
                Name = name.Replace("Controller", ""), Namespace = item.Namespace, MyActions = GetListOfAction(item)
            }).ToList();

        // Now we will get all areas that has been registered in route collection
        var getAllAreas = RouteTable.Routes.OfType<Route>()
            .Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area"))
            .Select(
                r =>
                    new MyArea
                    {
                        Name = r.DataTokens["area"].ToString(),
                        Namespace = r.DataTokens["Namespaces"] as IList<string>,
                    }).ToList()
            .Distinct().ToList();


        // Add a new area for default controllers
        getAllAreas.Insert(0, new MyArea()
        {
            Name = "Main",
            Namespace = new List<string>()
            {
                typeof (Web.Controllers.HomeController).Namespace
            }
        });


        foreach (var area in getAllAreas)
        {
            var temp = new List<MyController>();
            foreach (var item in area.Namespace)
            {
                temp.AddRange(getAllcontrollers.Where(x => x.Namespace == item).ToList());
            }
            area.MyControllers = temp;
        }

        return View(getAllAreas);
    }

    private static List<Type> GetSubClasses<T>()
    {
        return Assembly.GetCallingAssembly().GetTypes().Where(
            type => type.IsSubclassOf(typeof(T))).ToList();
    }

    private IEnumerable<MyAction> GetListOfAction(Type controller)
    {
        var navItems = new List<MyAction>();

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

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

            // 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 ChildActionOnlyAttribute)
                {
                    validAction = false;
                    break;
                }
                if (filter is HttpPostAttribute)
                {
                    isHttpPost = true;
                }

            }

            // Add the action to the list if it's "valid"
            if (validAction)
                navItems.Add(new MyAction()
                {
                    Name = action.ActionName,
                    IsHttpPost = isHttpPost
                });
        }
        return navItems;
    }

    public class MyAction
    {
        public string Name { get; set; }

        public bool IsHttpPost { get; set; }
    }

    public class MyController
    {
        public string Name { get; set; }

        public string Namespace { get; set; }

        public IEnumerable<MyAction> MyActions { get; set; }
    }

    public class MyArea
    {
        public string Name { get; set; }

        public IEnumerable<string> Namespace { get; set; }

        public IEnumerable<MyController> MyControllers { get; set; }
    }

为了获取操作,我使用了这个answer

如果你有更好的方法,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 2015-08-16
    • 1970-01-01
    • 2013-08-02
    相关资源
    最近更新 更多