Reputation: 255
i have an asp.net core 3.1 application and i want to get all controller , action and area names when my application is running like get action names with reflection in mvc. Is there any way ?
Upvotes: 1
Views: 4107
Reputation: 19
I wrote new code with a Controller and Action DisplayNames.
Assembly assembly = Assembly.GetExecutingAssembly();
var controllersList = assembly.GetTypes().Where(ctype => typeof(Controller).IsAssignableFrom(ctype)).Select(type => new { ty = type, methods = type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public).Where(y => Attribute.IsDefined(y, typeof(LogRequestAttribute))) }).Where(type => type.methods.Any(x => Attribute.IsDefined(x, typeof(LogRequestAttribute)))).Select(controller => new
{
AreaName = (controller.ty.GetCustomAttribute(typeof(AreaAttribute)) as AreaAttribute)?.RouteValue,
ControllerTitle = (controller.ty.GetCustomAttribute(typeof(DisplayNameAttribute)) as DisplayNameAttribute)?.DisplayName,
ControllerName = controller.ty.Name,
Actions = controller.methods.Select(action => new
{
ActionTitle = (action.GetCustomAttribute(typeof(DisplayNameAttribute)) as DisplayNameAttribute)?.DisplayName,
ActionName = action.Name,
}).ToList(),
}).ToList();
// group by on area
var areaList = controllersList.GroupBy(group => group.AreaName).Select(ar => new
{
AreaName = ar.Key,
Controllers = ar.Select(co => new
{
ControllerTitle = co.ControllerTitle,
ControllerName = co.ControllerName,
Actions = co.Actions,
}).ToList(),
}).ToList();
Upvotes: 0
Reputation: 8526
In my application I didn't require finding areas, so I ended up creating a simplified version based on the accepted answer. If it's useful to anyone else, here it is:
public static class ControllerActionEnumerator
{
public static List<ControllerAndItsActions> GetAllControllersAndTheirActions()
{
Assembly asm = Assembly.GetExecutingAssembly();
IEnumerable<Type> controllers = asm.GetTypes().Where(type => type.Name.EndsWith("Controller"));
var theList = new List<ControllerAndItsActions>();
foreach (Type curController in controllers)
{
List<string> actions = curController.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)
.Where(m => m.CustomAttributes.Any(a => typeof(HttpMethodAttribute).IsAssignableFrom(a.AttributeType)))
.Select(x => x.Name)
.ToList();
theList.Add(new ControllerAndItsActions(curController.Name, actions));
}
return theList;
}
}
public class ControllerAndItsActions
{
public string Controller { get; }
public List<string> Actions { get; }
public ControllerAndItsActions(string controller, List<string> actions) => (Controller, Actions) = (controller, actions);
}
Upvotes: 1
Reputation: 36765
Try this:
1.Model:
public class ControllerActions
{
public string Controller { get; set; }
public string Action { get; set; }
public string Area { get; set; }
}
2.Display the Controller,Action and Area Name:
[HttpGet]
public List<ControllerActions> Index()
{
Assembly asm = Assembly.GetExecutingAssembly();
var controlleractionlist = asm.GetTypes()
.Where(type => typeof(Controller).IsAssignableFrom(type))
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
.Select(x => new
{
Controller = x.DeclaringType.Name,
Action = x.Name,
Area = x.DeclaringType.CustomAttributes.Where(c => c.AttributeType == typeof(AreaAttribute))
}).ToList();
var list = new List<ControllerActions>();
foreach (var item in controlleractionlist)
{
if (item.Area.Count() != 0)
{
list.Add(new ControllerActions()
{
Controller = item.Controller,
Action = item.Action,
Area = item.Area.Select(v => v.ConstructorArguments[0].Value.ToString()).FirstOrDefault()
});
}
else
{
list.Add(new ControllerActions()
{
Controller = item.Controller,
Action = item.Action,
Area = null,
});
}
}
return list;
}
Upvotes: 4
Reputation: 259
Try this:
ControllerFeature controllerFeature = new ControllerFeature();
this.ApplicationPartManager.PopulateFeature(controllerFeature);
IEnumerable<TypeInfo> typeInfos = controllerFeature.Controllers;
ApplicationPartManager must use DI to your class.
Upvotes: 2