首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将所有区域、控制器和行动作为一棵树

将所有区域、控制器和行动作为一棵树
EN

Stack Overflow用户
提问于 2016-02-05 13:47:38
回答 1查看 1.5K关注 0票数 4

我需要得到所有已登记为列表的领域和他们所有的控制器作为子列表和相同的事情为行动。就像这样:

代码语言:javascript
复制
AdminArea
   HomeController
     Index
     Add
     ...
   OtherController
   ...
AnotherArea
   HomeController
      Index
      ...
...

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

更新

好的,用下面的代码,我可以得到所有的区域,通过第二个问题的回答,我可以得到所有的控制器,但是我无法确定每个控制器属于哪个区域。

代码语言:javascript
复制
var areaNames = RouteTable.Routes.OfType<Route>()
            .Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area"))
            .Select(r => r.DataTokens["area"]).ToList()
            .Distinct().ToList();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-10 14:01:49

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

代码语言:javascript
复制
    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

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35225796

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档