C# 以树的形式获取所有区域、控制器和操作

C# 以树的形式获取所有区域、控制器和操作,c#,asp.net-mvc-5,C#,Asp.net Mvc 5,我需要将所有已注册为列表的区域以及它们的所有控制器作为子列表进行操作。大概是这样的: AdminArea HomeController Index Add ... OtherController ... AnotherArea HomeController Index ... ... 我已经检查了问题的答案,还有这个,但它们不是我想要的。 第一个返回所有已注册的路由,第二个返回所有控制器 更新 好的,通过下面的代码,

我需要将所有已注册为列表的区域以及它们的所有控制器作为子列表进行操作。大概是这样的:

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

更新

好的,通过下面的代码,我可以得到所有的区域,通过第二个问题的答案,我可以得到所有的控制器,但是我不能确定每个控制器都属于哪个区域

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

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

    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; }
    }
公共虚拟操作结果索引()
{
var list=getsubclass();
//获取所有控制器及其操作
var getAllcontrollers=(来自列表中的项
让name=item.name
where!item.Name.StartsWith(“T4MVC”)//我正在使用T4MVC
选择新的MyController()
{
Name=Name.Replace(“控制器”),Namespace=item.Namespace,MyActions=GetListOfAction(项)
}).ToList();
//现在,我们将获取已在route collection中注册的所有区域
var getallreas=RouteTable.Routes.OfType()的值
.Where(d=>d.DataTokens!=null&&d.DataTokens.ContainsKey(“区域”))
.选择(
r=>
新MyArea
{
Name=r.DataTokens[“区域”].ToString(),
Namespace=r.DataTokens[“Namespaces”]作为IList,
})托利斯先生()
.Distinct().ToList();
//为默认控制器添加新区域
getAllAreas.Insert(0,新的MyArea()
{
Name=“Main”,
名称空间=新列表()
{
typeof(Web.Controllers.HomeController).命名空间
}
});
foreach(getAllAreas的var区域)
{
var temp=新列表();
foreach(area.Namespace中的变量项)
{
temp.AddRange(getAllController.Where(x=>x.Namespace==item.ToList());
}
area.MyControllers=温度;
}
返回视图(getAllAreas);
}
私有静态列表getSubclass()
{
返回Assembly.GetCallingAssembly().GetTypes().Where(
type=>type.IsSubclassOf(typeof(T))).ToList();
}
私有IEnumerable GetListOfAction(类型控制器)
{
var navItems=新列表();
//获取此控制器的描述符
ReflectedControllerDescriptor controllerDesc=新的ReflectedControllerDescriptor(控制器);
//查看控制器中的每个操作
foreach(controllerDesc.GetCanonicalActions()中的ActionDescriptor操作)
{
布尔有效性=真;
bool-ishttpost=false;
//获取操作的任何属性(筛选器)
object[]attributes=action.GetCustomAttributes(false);
//查看每个属性
foreach(属性中的对象过滤器)
{
//我们可以导航到动作吗?
如果(筛选器为ChildActionOnlyAttribute)
{
有效性=假;
打破
}
if(筛选器为HttpPostAttribute)
{
ishttpost=true;
}
}
//如果操作“有效”,则将其添加到列表中
if(有效期)
添加(新的MyAction()
{
Name=action.ActionName,
IsHttpPost=IsHttpPost
});
}
返回navItems;
}
公共集体诉讼
{
公共字符串名称{get;set;}
公共bool ishttpost{get;set;}
}
公共类MyController
{
公共字符串名称{get;set;}
公共字符串命名空间{get;set;}
公共IEnumerable MyActions{get;set;}
}
公共类MyArea
{
公共字符串名称{get;set;}
公共IEnumerable命名空间{get;set;}
公共IEnumerable MyController{get;set;}
}
为了得到行动,我用了这个


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

为什么这些问题不是您想要的?请帮助我们了解它们为什么不适合您。我检查了两个链接,它们一起提供了实现您要求的所有信息。做一些工作,如果你陷入困境,展示你所做的,也许社区会尽力帮助你,而不是为你做这些工作。