2016-02-05 69 views
3

我需要获取已注册为列表和所有控制器的所有区域作为子列表和操作的相同事物。是这样的:获取所有区域,控制器和操作作为树

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(); 
+2

为什么这些问题不是你要找的?帮助我们知道他们为什么不为你工作。 – krillgar

+0

我检查这两个链接,并一起他们有你需要的所有信息,以实现你的要求。做一些工作,展示如果你陷入困境,你会做什么,也许社区会试图帮助你,而不是为你做好工作。 – Nkosi

回答

2

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

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

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

相关问题