2012-07-02 10 views
12

Come posso ottenere l'elenco di tutte le azioni del Controller? Cerco ma non riesco a trovare un esempio/risposta. Vedo qualche esempio consigliato usando il riflesso ma non so come.Come posso ottenere l'elenco di tutte le azioni di MVC Controller passando ControllerName?

Ecco quello che sto cercando di fare:

public List<string> ActionNames(string controllerName){ 




} 
+0

Ho intenzione di mettere un commento qui, perché è generale. Per quello che stai cercando di fare (nomi di azioni del controller) non è il modo in cui dovrebbe essere fatto. Potrebbero esserci diverse azioni con lo stesso nome e alcune potrebbero essere solo Ajax, ecc. Ecc. Le tue autorizzazioni dovrebbero essere basate su azioni diverse da quelle del controller. –

risposta

21

Non ci ha detto perché avete bisogno di questo, ma una possibilità è quella di utilizzare la riflessione:

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

Ovviamente come sappiamo riflessione non è molto veloce, quindi se intendi chiamare questo metodo spesso potresti considerare di migliorarlo memorizzando nella cache l'elenco dei controller per evitare di scaricarlo sempre e persino il metodo memoizing per i parametri di input forniti.

+0

Grazie !!! Nella mia applicazione, ho bisogno di creare una pagina di autorizzazione per l'utente amministratore. L'amministratore seleziona un nome di controller da dropdownlist, quindi l'elenco di azioni viene visualizzato dinamicamente in base al nome del controller selezionato. Quindi assegnare tali valori a utenti/ruoli. – nannypooh

+0

Ho ricevuto l'errore "da t in a.GetTypes() - Impossibile caricare uno o più dei tipi richiesti." – nannypooh

+0

Vale la pena sottolineare che il metodo GetCanonicalActions di ReflectedControllerDescriptor restituirà un ActionDescriptor per ogni metodo pubblico sul controller, inclusi i metodi che non sono azioni. Ignora anche il NonActionAttribute. – rossisdead

0

Un piccolo ritocco per la risposta di Darin. Avevo bisogno di questa modifica per far sì che funzionasse con codice lente mentre veniva eseguito con un assembly diverso.

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(); 
} 
Problemi correlati