1

How do I create action links for all actions in the site?
I want to put those action links into a menu system.

I was hoping I can do something like

foreach controller in controllers {
    foreach action in controller{
        stringbuilder.writeline(
            "<li>"+actionlink(menu, action, controller)+"<li>"
        );
    }
}
ton.yeung
  • 4,793
  • 6
  • 41
  • 72

2 Answers2

2

Here's my take on it:

var controllers = Assembly.GetCallingAssembly().GetTypes().Where(type => type.IsSubclassOf(typeof(Controller))).ToList();
var controlList = controllers.Select(controller =>
                                     new
                                     {
                                         Actions = GetActions(controller),
                                         Name = controller.Name,
                                     }).ToList();

The method GetActions as follows:

public static List<String> GetActions(Type controller)
{
    // List of links
    var items = new List<String>();

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

    // Look at each action in the controller
    foreach (var action in controllerDesc.GetCanonicalActions())
    {
        // Get any attributes (filters) on the action
        var attributes = action.GetCustomAttributes(false);

        // Look at each attribute
        var validAction =
            attributes.All(filter => !(filter is HttpPostAttribute) && !(filter is ChildActionOnlyAttribute));

        // Add the action to the list if it's "valid"
        if (validAction)
           items.Add(action.ActionName);
    }
    return items;
}

If you need a menu system checkout the MVC Sitemap Provider, it will give you absolute control on what to render depending on the roles you've defined on your membership implementation.

amhed
  • 3,649
  • 2
  • 31
  • 56
  • I've looked at the provider, maybe i need to look a little more, but it looks like I need to define the menus through xml? – ton.yeung Apr 06 '13 at 22:38
  • Yes, you would have to define the menus using XML. But you can use the code I provided to get the initial list (you still need to define which roles can access which action anyways) – amhed Apr 07 '13 at 02:07
  • We have a custom permissions based authorization that allows the users to define that. Its a multi tenant system, so it was either going to have to be table based or conventions based. We trying to get the latter working. – ton.yeung Apr 08 '13 at 16:01
  • 1
    That works, but only if I change out Assembly.GetCallingAssembly() with Assembly.GetExecutingAssembly() – ton.yeung Apr 08 '13 at 16:40
0

Here is approach how get all actions from controller Asp.net Mvc: List all the actions on a controller with specific attribute or Accessing the list of Controllers/Actions in an ASP.NET MVC application For achieving your goal you should find all controllers in your project with Assembly.GetExportedTypes() and filter only sub classes of ControllerBase and for each controller call new ReflectedControllerDescriptor(typeof(TController)).GetCanonicalActions() from 2nd link.

Community
  • 1
  • 1
Vladimirs
  • 8,232
  • 4
  • 43
  • 79