Reputation: 7240
Is there a way to get a list of all Actions Methods of my MVC 3 project?
Upvotes: 6
Views: 6715
Reputation: 9294
This will give you a dictionary with the controller type as key and an IEnumerable of its MethodInfos as value.
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)));
It looks in more than just the current assembly and it will also return methods that, for example, return JsonResult instead of ActionResult. (JsonResult actually inherits from ActionResult)
Edit: For Web API support
Change
&& typeof(IController).IsAssignableFrom(t)); // should implement IController (happens automatically when you extend Controller)
to
&& typeof(IHttpController).IsAssignableFrom(t)); // should implement IHttpController (happens automatically when you extend ApiController)
and remove this:
.Where(m => typeof(ActionResult).IsAssignableFrom(m.ReturnType))
Because Web API methods can return just about anything. (POCO's, HttpResponseMessage, ...)
Upvotes: 10
Reputation: 1400
You can use this to reflect over the assemblies at runtime to produce a list of methods in Controllers that return 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)
)
);
}
This will give you the actions, but not the list of Views (i.e. it won't work if you can use different views in each action)
Upvotes: 7