Skip to content

Instantly share code, notes, and snippets.

@ermish
Created March 12, 2018 00:28
Show Gist options
  • Save ermish/745e48389a614e05e033e12eed173999 to your computer and use it in GitHub Desktop.
Save ermish/745e48389a614e05e033e12eed173999 to your computer and use it in GitHub Desktop.
Helper Utility to find all actions on a .NET MVC Project. Useful for API Documentation
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Microsoft.Ajax.Utilities;
namespace Helpers.Web
{
public class ControllerDesc
{
public string Name { get; set; }
public string Area { get; set; }
public List<ActionDesc> Actions { get; set; }
}
public class ActionDesc
{
public string Name { get; set; }
}
public static class MVCActionsFinder
{
public static List<ControllerDesc> GetControllerDescs(Type aType = null)
{
var assembly = aType == null ? Assembly.GetExecutingAssembly() : aType.Assembly;
var controllers = assembly
.GetTypes()
.Where(t => !t.IsInterface)
.ToList()
.Where(t => t.BaseType == typeof(Controller) || t.BaseType.BaseType != null && t.BaseType.BaseType == typeof(Controller));
var actions = controllers.SelectMany(t => t.GetMethods()).Where(m => m.IsPublic && !m.IsSpecialName && (
m.ReturnType == typeof(ActionResult)
|| m.ReturnType.BaseType == typeof(ActionResult)
|| (m.ReturnType.BaseType != null && m.ReturnType.BaseType.BaseType == typeof(ActionResult))
));
var results = actions.GroupBy(a => a.DeclaringType.Name.Replace("Controller", string.Empty))
.Select(g =>
new ControllerDesc
{
Name = g.Key,
Area = FindAreaForControllerType(g.GetType()),
Actions = g.Select(a => a.Name)
.Distinct()
.Select(a => new ActionDesc { Name = a })
.ToList()
})
.ToList();
var areas = results.Select(x => x.Area).Distinct(); 
foreach (var area in areas)
{
var controller = results.Where(x => x.Area == area);
}
foreach (var controller in results.Where(x => x.Area.IsNullOrWhiteSpace()))
{
}
return results;
}
private static string FindAreaForControllerType(Type controllerType)
{
var areaTypes = GetAllAreasRegistered();
foreach (var areaType in areaTypes)
{
if (controllerType.Namespace.StartsWith(areaType.Namespace))
{
var area = (AreaRegistration)Activator.CreateInstance(areaType);
return area.AreaName;
}
}
return string.Empty;
}
private static IEnumerable<Type> GetAllAreasRegistered()
{
var assembly = GetWebEntryAssembly();
var areaTypes = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(AreaRegistration)));
return areaTypes;
}
private static Assembly GetWebEntryAssembly()
{
var assembly = Assembly.GetExecutingAssembly();
return assembly;
if (System.Web.HttpContext.Current == null || System.Web.HttpContext.Current.ApplicationInstance == null)
{
return null;
}
var type = System.Web.HttpContext.Current.ApplicationInstance.GetType();
while (type != null && type.Namespace == "ASP")
{
type = type.BaseType;
}
return type == null ? null : type.Assembly;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment