【问题标题】:How to get all action , controller and area names while running asp core 3.1如何在运行 asp core 3.1 时获取所有操作、控制器和区域名称
【发布时间】:2020-01-13 13:12:51
【问题描述】:

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

【问题讨论】:

标签: asp.net-mvc asp.net-mvc-4 asp.net-core reflection .net-core


【解决方案1】:

试试这个:

1.型号:

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

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

[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;
}

【讨论】:

    【解决方案2】:

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

    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);
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      【解决方案4】:

      试试这个:

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

      ApplicationPartManager 必须对您的类使用 DI。

      【讨论】:

      • 我应该在哪里使用这个代码??你能举个例子吗!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多