Obtener todos los nombres de Controladores y Acciones en C #

¿Es posible enumerar los nombres de todos los controladores y sus acciones mediante progtwigción?

Quiero implementar seguridad basada en bases de datos para cada controlador y acción. Como desarrollador, conozco todos los controladores y acciones y puedo agregarlos a una tabla de base de datos, pero ¿hay alguna manera de agregarlos automáticamente?

Puede usar la reflexión para encontrar todos los Controladores en el ensamblado actual, y luego encontrar sus métodos públicos que no están decorados con el atributo NonAction .

 Assembly asm = Assembly.GetExecutingAssembly(); asm.GetTypes() .Where(type=> typeof(Controller).IsAssignableFrom(type)) //filter controllers .SelectMany(type => type.GetMethods()) .Where(method => method.IsPublic && ! method.IsDefined(typeof(NonActionAttribute))); 

Lo siguiente extraerá controladores, acciones, atributos y tipos de devolución:

 Assembly asm = Assembly.GetAssembly(typeof(MyWebDll.MvcApplication)); var controlleractionlist = asm.GetTypes() .Where(type=> typeof(System.Web.Mvc.Controller).IsAssignableFrom(type)) .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)) .Where(m => !m.GetCustomAttributes(typeof( System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any()) .Select(x => new {Controller = x.DeclaringType.Name, Action = x.Name, ReturnType = x.ReturnType.Name, Attributes = String.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute",""))) }) .OrderBy(x=>x.Controller).ThenBy(x => x.Action).ToList(); 

Si ejecuta este código en linqpad, por ejemplo, y llama

 controlleractionlist.Dump(); 

obtienes el siguiente resultado:

enter image description here

Estaba buscando una forma de obtener Área, Controlador y Acción, y para esto logro cambiar un poco los métodos que publicas aquí, así que si alguien está buscando una manera de obtener el ÁREA aquí está mi método feo (que guardo para un xml):

  public static void GetMenuXml() { var projectName = Assembly.GetExecutingAssembly().FullName.Split(',')[0]; Assembly asm = Assembly.GetAssembly(typeof(MvcApplication)); var model = asm.GetTypes(). SelectMany(t => t.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)) .Where(d => d.ReturnType.Name == "ActionResult").Select(n => new MyMenuModel() { Controller = n.DeclaringType?.Name.Replace("Controller", ""), Action = n.Name, ReturnType = n.ReturnType.Name, Attributes = string.Join(",", n.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", ""))), Area = n.DeclaringType.Namespace.ToString().Replace(projectName + ".", "").Replace("Areas.", "").Replace(".Controllers", "").Replace("Controllers", "") }); SaveData(model.ToList()); } 

Editar:

 //assuming that the namespace is ProjectName.Areas.Admin.Controllers Area=n.DeclaringType.Namespace.Split('.').Reverse().Skip(1).First() 

Use Reflection , enumere todos los tipos dentro del ensamblaje y las clases de filtro heredadas de System.Web.MVC.Controller , que enumeren los métodos públicos de este tipo como acciones

 Assembly assembly = Assembly.LoadFrom(sAssemblyFileName) IEnumerable types = assembly.GetTypes().Where(type => typeof(Controller).IsAssignableFrom(type)).OrderBy(x => x.Name); foreach (Type cls in types) { list.Add(cls.Name.Replace("Controller", "")); IEnumerable memberInfo = cls.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public).Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any()).OrderBy(x => x.Name); foreach (MemberInfo method in memberInfo) { if (method.ReflectedType.IsPublic && !method.IsDefined(typeof(NonActionAttribute))) { list.Add("\t" + method.Name.ToString()); } } } 
 var result = Assembly.GetExecutingAssembly() .GetTypes() .Where(type => typeof(ApiController).IsAssignableFrom(type)) .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)) .Where(m => !m.GetCustomAttributes(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), true).Any()) .GroupBy(x => x.DeclaringType.Name) .Select(x => new { Controller = x.Key, Actions = x.Select(s => s.Name).ToList() }) .ToList(); 

@decastro la respuesta es buena. Agrego este filtro para devolver solo las acciones públicas que el desarrollador haya declarado.

  var asm = Assembly.GetExecutingAssembly(); var methods = asm.GetTypes() .Where(type => typeof(Controller) .IsAssignableFrom(type)) .SelectMany(type => type.GetMethods()) .Where(method => method.IsPublic && !method.IsDefined(typeof(NonActionAttribute)) && ( method.ReturnType==typeof(ActionResult) || method.ReturnType == typeof(Task) || method.ReturnType == typeof(String) || //method.ReturnType == typeof(IHttpResult) || ) ) .Select(m=>m.Name); 

O, para reducir la idea de @dcastro y simplemente obtener los controladores:

 Assembly.GetExecutingAssembly() .GetTypes() .Where(type => typeof(Controller).IsAssignableFrom(type))