2012-07-02 14 views
12

¿Cómo puedo obtener la lista de todas las acciones de Controller? Busco pero no puedo encontrar el ejemplo/respuesta. Veo algunos ejemplos recomendados usando la reflexión, pero no sé cómo.¿Cómo puedo obtener la lista de todas las acciones de MVC Controller al pasar ControllerName?

Aquí es lo que estoy tratando de hacer:

public List<string> ActionNames(string controllerName){ 




} 
+0

Voy a poner un comentario aquí, porque es general. Por lo que está tratando de hacer (nombres de acciones de controlador) no es la forma en que debería hacerse. Puede haber varias acciones con el mismo nombre y algunas pueden ser solo Ajax, etc. Sus permisos deben basarse en otras cosas que no sean acciones del controlador. –

Respuesta

21

No nos ha dicho por qué necesita esto, pero una posibilidad es utilizar la reflexión:

public List<string> ActionNames(string controllerName) 
{ 
    var types = 
     from a in AppDomain.CurrentDomain.GetAssemblies() 
     from t in a.GetTypes() 
     where typeof(IController).IsAssignableFrom(t) && 
       string.Equals(controllerName + "Controller", t.Name, StringComparison.OrdinalIgnoreCase) 
     select t; 

    var controllerType = types.FirstOrDefault(); 

    if (controllerType == null) 
    { 
     return Enumerable.Empty<string>().ToList(); 
    } 
    return new ReflectedControllerDescriptor(controllerType) 
     .GetCanonicalActions().Select(x => x.ActionName) 
     .ToList(); 
} 

Obviamente como sabemos reflexión no es muy rápido, por lo tanto, si tiene la intención de llamar a este método con frecuencia, puede considerar mejorarlo almacenando en la memoria caché la lista de controladores para evitar buscarlo cada vez e incluso memoizing el método para los parámetros de entrada dados.

+0

¡Gracias! En mi aplicación, necesito crear una página de permisos para el usuario administrador. El administrador seleccionará un nombre de controlador de la lista desplegable, luego la lista de acciones se mostraría dinámicamente en función del nombre del controlador seleccionado. Luego asigne esos valores a los usuarios/roles. – nannypooh

+0

Recibí el error "de t en a.GetTypes() - No se pueden cargar uno o más de los tipos solicitados". – nannypooh

+0

Vale la pena señalar que el método GetCanonicalActions de ReflectedControllerDescriptor devolverá un ActionDescriptor para cada método público en el controlador, incluidos los métodos que no son acciones. También ignora NonActionAttribute. – rossisdead

0

Un ligero ajuste a la respuesta de Darin. Necesitaba este cambio para que esto funcione con Code Lense, ya que se ejecuta bajo un ensamblaje diferente.

public static List<string> GetAllActionNames(string controllerName) 
{ 
    var controllerType = Assembly.Load("YourAssemblyNameHere") 
     .GetTypes() 
     .FirstOrDefault(x => typeof(IController).IsAssignableFrom(x) 
      && x.Name.Equals(controllerName + "Controller", StringComparison.OrdinalIgnoreCase)); 

    if (controllerType == null) 
    { 
     return Enumerable.Empty<string>().ToList(); 
    } 
    return new ReflectedControllerDescriptor(controllerType) 
     .GetCanonicalActions().Select(x => x.ActionName) 
     .ToList(); 
} 
Cuestiones relacionadas