如何在 运行 asp core 3.1 时获取所有动作、控制器和区域名称

How to get all action , controller and area names while running asp core 3.1

我有一个 asp.net 核心 3.1 应用程序,我想在我的应用程序 运行 时获取所有控制器、操作和区域名称,例如在 mvc 中使用反射获取操作名称。 有什么办法吗?

试试这个:

ControllerFeature controllerFeature = new ControllerFeature();
this.ApplicationPartManager.PopulateFeature(controllerFeature);
IEnumerable<TypeInfo> typeInfos = controllerFeature.Controllers;

ApplicationPartManager 必须使用 DI 到您的 class。

试试这个:

1.Model:

public class ControllerActions
{
    public string Controller { get; set; }
    public string Action { get; set; }
    public string Area { get; set; }
}

2.Display控制器、动作和区域名称:

[HttpGet]
public List<ControllerActions> Index()
{
    Assembly asm = Assembly.GetExecutingAssembly();
    var controlleractionlist = asm.GetTypes()
            .Where(type => typeof(Controller).IsAssignableFrom(type))
            .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
            .Select(x => new
            {
                Controller = x.DeclaringType.Name,
                Action = x.Name,
                Area = x.DeclaringType.CustomAttributes.Where(c => c.AttributeType == typeof(AreaAttribute))

            }).ToList();
    var list = new List<ControllerActions>();
    foreach (var item in controlleractionlist)
    {
        if (item.Area.Count() != 0)
        {
            list.Add(new ControllerActions()
            {
                Controller = item.Controller,
                Action = item.Action,
                Area = item.Area.Select(v => v.ConstructorArguments[0].Value.ToString()).FirstOrDefault()
            });
        }
        else
        {
            list.Add(new ControllerActions()
            {
                Controller = item.Controller,
                Action = item.Action,
                Area = null,
            });
        }
    }
    return list;
}

在我的应用程序中,我不需要查找 区域 ,因此我最终根据已接受的答案创建了一个简化版本。如果它对其他人有用,这里是:

public static class ControllerActionEnumerator
{
    public static List<ControllerAndItsActions> GetAllControllersAndTheirActions()
    {
        Assembly asm = Assembly.GetExecutingAssembly();
        IEnumerable<Type> controllers = asm.GetTypes().Where(type => type.Name.EndsWith("Controller"));
        var theList = new List<ControllerAndItsActions>();
        
        foreach (Type curController in controllers)
        {
            List<string> actions = curController.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)
                .Where(m => m.CustomAttributes.Any(a => typeof(HttpMethodAttribute).IsAssignableFrom(a.AttributeType)))
                .Select(x => x.Name)
                .ToList();
            
            theList.Add(new ControllerAndItsActions(curController.Name, actions));
        }

        return theList;
    }
}

public class ControllerAndItsActions
{
    public string Controller { get; }
    public List<string> Actions { get; }

    public ControllerAndItsActions(string controller, List<string> actions) => (Controller, Actions) = (controller, actions);
}

我用控制器和动作显示名称编写了新代码。

Assembly assembly = Assembly.GetExecutingAssembly();

        var controllersList = assembly.GetTypes().Where(ctype => typeof(Controller).IsAssignableFrom(ctype)).Select(type => new { ty = type, methods = type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public).Where(y => Attribute.IsDefined(y, typeof(LogRequestAttribute))) }).Where(type => type.methods.Any(x => Attribute.IsDefined(x, typeof(LogRequestAttribute)))).Select(controller => new
        {
            AreaName = (controller.ty.GetCustomAttribute(typeof(AreaAttribute)) as AreaAttribute)?.RouteValue,
            ControllerTitle = (controller.ty.GetCustomAttribute(typeof(DisplayNameAttribute)) as DisplayNameAttribute)?.DisplayName,
            ControllerName = controller.ty.Name,
            Actions = controller.methods.Select(action => new
            {
                ActionTitle = (action.GetCustomAttribute(typeof(DisplayNameAttribute)) as DisplayNameAttribute)?.DisplayName,
                ActionName = action.Name,
            }).ToList(),
        }).ToList();

        // group by on area
        var areaList = controllersList.GroupBy(group => group.AreaName).Select(ar => new
        {
            AreaName = ar.Key,
            Controllers = ar.Select(co => new
            {
                ControllerTitle = co.ControllerTitle,
                ControllerName = co.ControllerName,
                Actions = co.Actions,
            }).ToList(),
        }).ToList();