Getting All Controllers and Actions Names in C#

Getting All Controllers and Actions names in C#

You can use reflection to find all Controllers in the current assembly, and then find their public methods that are not decorated with the NonAction attribute.

Assembly asm = Assembly.GetExecutingAssembly();

asm.GetTypes()
.Where(type=> typeof(Controller).IsAssignableFrom(type)) //filter controllers
.SelectMany(type => type.GetMethods())
.Where(method => method.IsPublic && ! method.IsDefined(typeof(NonActionAttribute)));

How to get all action , controller and area names while running asp core 3.1

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

How to Find All Controller and Action

How about injecting IActionDescriptorCollectionProvider to your component that needs to know these things? It's in the Microsoft.AspNetCore.Mvc.Infrastructure namespace.

This component gives you every single action available in the app. Here is an example of the data it provides:

Action descriptor collection provider data sample

As a bonus, you can also evaluate all of the filters, parameters etc.


As a side note, I suppose you could use reflection to find the types that inherit from ControllerBase. But did you know you can have controllers that don't inherit from it? And that you can write conventions that override those rules? For this reason, injecting the above component makes it a lot easier. You don't need to worry about it breaking.

Get controller and action name from within controller?

string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();

How to get all action names from a controller

There's no generic solution for this, because I could write a custom attribute derived from ActionNameSelectorAttribute and override IsValidName with any custom code, even code that compares the name to a random GUID. There is no way for you to know, in this case, which action name the attribute will accept.

If you constrain your solution to only considering the method name or the built-in ActionNameAttribute then you can reflect over the class to get all the names of public methods that return an ActionResult and check whether they have an ActionNameAttribute whose Name property overrides the method name.

Get all Area, Controller and Action as a tree

So here is what i came up with, it's exactly what i wanted.
I hope it will be helpful.

    public virtual ActionResult Index()
{
var list = GetSubClasses<Controller>();

// Get all controllers with their actions
var getAllcontrollers = (from item in list
let name = item.Name
where !item.Name.StartsWith("T4MVC_") // I'm using T4MVC
select new MyController()
{
Name = name.Replace("Controller", ""), Namespace = item.Namespace, MyActions = GetListOfAction(item)
}).ToList();

// Now we will get all areas that has been registered in route collection
var getAllAreas = RouteTable.Routes.OfType<Route>()
.Where(d => d.DataTokens != null && d.DataTokens.ContainsKey("area"))
.Select(
r =>
new MyArea
{
Name = r.DataTokens["area"].ToString(),
Namespace = r.DataTokens["Namespaces"] as IList<string>,
}).ToList()
.Distinct().ToList();

// Add a new area for default controllers
getAllAreas.Insert(0, new MyArea()
{
Name = "Main",
Namespace = new List<string>()
{
typeof (Web.Controllers.HomeController).Namespace
}
});

foreach (var area in getAllAreas)
{
var temp = new List<MyController>();
foreach (var item in area.Namespace)
{
temp.AddRange(getAllcontrollers.Where(x => x.Namespace == item).ToList());
}
area.MyControllers = temp;
}

return View(getAllAreas);
}

private static List<Type> GetSubClasses<T>()
{
return Assembly.GetCallingAssembly().GetTypes().Where(
type => type.IsSubclassOf(typeof(T))).ToList();
}

private IEnumerable<MyAction> GetListOfAction(Type controller)
{
var navItems = new List<MyAction>();

// Get a descriptor of this controller
ReflectedControllerDescriptor controllerDesc = new ReflectedControllerDescriptor(controller);

// Look at each action in the controller
foreach (ActionDescriptor action in controllerDesc.GetCanonicalActions())
{
bool validAction = true;
bool isHttpPost = false;

// Get any attributes (filters) on the action
object[] attributes = action.GetCustomAttributes(false);

// Look at each attribute
foreach (object filter in attributes)
{
// Can we navigate to the action?
if (filter is ChildActionOnlyAttribute)
{
validAction = false;
break;
}
if (filter is HttpPostAttribute)
{
isHttpPost = true;
}

}

// Add the action to the list if it's "valid"
if (validAction)
navItems.Add(new MyAction()
{
Name = action.ActionName,
IsHttpPost = isHttpPost
});
}
return navItems;
}

public class MyAction
{
public string Name { get; set; }

public bool IsHttpPost { get; set; }
}

public class MyController
{
public string Name { get; set; }

public string Namespace { get; set; }

public IEnumerable<MyAction> MyActions { get; set; }
}

public class MyArea
{
public string Name { get; set; }

public IEnumerable<string> Namespace { get; set; }

public IEnumerable<MyController> MyControllers { get; set; }
}

For getting actions, i used this answer.

If you have any better ways, please let me know.



Related Topics



Leave a reply



Submit