2011-04-27 2 views
3

Existe-t-il un moyen d'obtenir une liste de toutes les méthodes d'actions de mon projet MVC 3?MVC obtenir toutes les méthodes d'action

+0

Lors de l'exécution ou dans VS? – Richard

+0

Voulez-vous dire Actions ou Vues? Si vous voulez dire Vues, ​​incluez-vous des vues partielles? Aussi quel viewengine? Si vous utilisez la valeur par défaut, vous pouvez utiliser la réflexion pour obtenir une liste de chaque classe de votre assembly/namespace qui hérite de System.Web.Mvc.ViewPage ou de ViewPage . Actions que vous pouvez faire le même genre de chose - utilisez la réflexion pour identifier toutes les classes héritées de Controller et toutes leurs méthodes publiques qui retournent une dérivée ActionResult. – RichardW1001

+0

Je veux les Actions dans VS –

Répondre

7

Vous pouvez l'utiliser pour réfléchir sur les assemblées lors de l'exécution pour produire une liste des méthodes dans un contrôleur qui retournent ActionResult:

public IEnumerable<MethodInfo> GetMvcActionMethods() 
    { 
     return 
      Directory.GetFiles(Assembly.GetExecutingAssembly().Location) 
       .Select(Assembly.LoadFile) 
       .SelectMany(
        assembly => 
        assembly.GetTypes() 
          .Where(t => typeof (Controller).IsAssignableFrom(t)) 
          .SelectMany(type => (from action in type.GetMethods(BindingFlags.Public | BindingFlags.Instance) 
               where action.ReturnType == typeof(ActionResult) 
               select action) 
             ) 
        ); 
    } 

Cela vous donnera les actions, mais pas la liste des vues (il ne fonctionnera pas si vous pouvez utiliser différentes vues dans chaque action)

+1

Cette méthode ne comprendra pas les méthodes d'action qui renvoient "FileContentResult", "JsonResult", ... Voir ma réponse ci-dessous – Moeri

8

Cela vous donnera un dictionnaire avec le type de contrôleur comme clé et un IEnumerable de sa valeur MethodInfos.

 var assemblies = AppDomain.CurrentDomain.GetAssemblies(); // currently loaded assemblies 
     var controllerTypes = assemblies 
      .SelectMany(a => a.GetTypes()) 
      .Where(t => t != null 
       && t.IsPublic // public controllers only 
       && t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) // enfore naming convention 
       && !t.IsAbstract // no abstract controllers 
       && typeof(IController).IsAssignableFrom(t)); // should implement IController (happens automatically when you extend Controller) 
     var controllerMethods = controllerTypes.ToDictionary(
      controllerType => controllerType, 
      controllerType => controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(m => typeof(ActionResult).IsAssignableFrom(m.ReturnType))); 

Il semble plus que juste l'assemblée en cours et il sera également de retour des méthodes qui, par exemple, au lieu de JsonResult reviennent ActionResult. (JsonResult hérite en fait de ActionResult)

Edit: Pour le support de l'API Web

changement

&& typeof(IController).IsAssignableFrom(t)); // should implement IController (happens automatically when you extend Controller) 

à

&& typeof(IHttpController).IsAssignableFrom(t)); // should implement IHttpController (happens automatically when you extend ApiController) 

et supprimer ce:

.Where(m => typeof(ActionResult).IsAssignableFrom(m.ReturnType)) 

Be Les méthodes de l'API Web peuvent renvoyer à peu près n'importe quoi. (POCO, HttpResponseMessage, ...)

+0

+1 pour une méthode qui retourne plus de détails (j'aime comment elle regroupe les 'Actions' avec leurs 'respectifs' Controllers ') – JakeJ

+0

Dans le cas de webapi ce code obtient beaucoup de méthodes redondantes - constructeurs, toutes les propriétés publiques (héritées de ApiController), etc. Méthode plus précise décrite ici: http://stackoverflow.com/questions/28069206/how-can- i-get-la-liste-de-toutes-les-actions-de-apicontroller – LbISS

Questions connexes