将所有区域,控制器和动作作为树

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

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

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

更新

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

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

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

  public virtual ActionResult Index() { var list = GetSubClasses(); // 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() .Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area")) .Select( r => new MyArea { Name = r.DataTokens["area"].ToString(), Namespace = r.DataTokens["Namespaces"] as IList, }).ToList() .Distinct().ToList(); // Add a new area for default controllers getAllAreas.Insert(0, new MyArea() { Name = "Main", Namespace = new List() { typeof (Web.Controllers.HomeController).Namespace } }); foreach (var area in getAllAreas) { var temp = new List(); foreach (var item in area.Namespace) { temp.AddRange(getAllcontrollers.Where(x => x.Namespace == item).ToList()); } area.MyControllers = temp; } return View(getAllAreas); } private static List GetSubClasses() { return Assembly.GetCallingAssembly().GetTypes().Where( type => type.IsSubclassOf(typeof(T))).ToList(); } private IEnumerable GetListOfAction(Type controller) { var navItems = new List(); // 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 MyActions { get; set; } } public class MyArea { public string Name { get; set; } public IEnumerable Namespace { get; set; } public IEnumerable MyControllers { get; set; } } 

为了获得行动,我使用了这个答案 。

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