9

I've been trying to come up with a way to create a dynamic role based navigation solution for a project that I am working on.

The navigation should display only links that are relative to the users role, for example: an administrator will have links to view application statistics, manage customer accounts, ect... while a standard user would have links to manage their account, communicate with friends, ect..

I currently have a single partial view called Navigation with some basic conditional statements for role checking and a mix of markup for displaying the appropriate links. This works, but, I know it could quickly become unmanageable.

Navigation Partial View:

@if(User.IsInRole("Admin")) {
    <li><a href="#">Statistics</a></li>
    <li><a href="#">Accounts</a></li>
    <li><a href="#">Dashboard</a></li>
} 
@if(User.IsInRole("User")) {
    <li><a href="#">Account</a></li>
    <li><a href="#">Friends</a></li>
}
// code omitted

Is there a way to get this logic out of the view and let the Controller handle this?

matt.
  • 2,355
  • 5
  • 32
  • 43
  • 1
    does your Partial use a child Action method? – Dave Alperovich Jun 09 '13 at 18:28
  • Thanks Dave. No it does not. Haven't really used Child Actions before. Would you mind expanding on your question? I'm not sure what role child actions would play in this scenario. – matt. Jun 09 '13 at 19:22
  • 4
    Child actions are great. They are actions that pass a model back to you partial. you would call them `Action("/Controller/Action/id")`. The id part can be your handle to which nav you want to create and the model can be a list of nav items. Even better, your child action can look up your users role without argument and return the proper nav bar. I've used this for role based navigation before. – Dave Alperovich Jun 09 '13 at 19:49

1 Answers1

14

SOLUTION

As suggested, I created a ChildAction called Menu and partial views for each role. Inside the action I do some role checking using some conditional statements and render the appropriate view.

This keeps the conditional statements out of the views which makes it a lot cleaner solution.

I'm sure there are a few things that could be done to tidy it up and I will continue trying to improve it.

Here is the solution I used.

In the layout view where I wanted the menu to appear I used this.

@Html.Action("Menu", "Navigation")

Then I created a controller called Navigation and added a single Action called Menu.

public class NavigationController : Controller
{

    [ChildActionOnly]
    public ActionResult Menu()
    {
        if (Roles.IsUserInRole("Administrator"))
        {
            return PartialView("_NavigationAdmin");

        }

        return PartialView("_NavigationPublic");
    }

}
matt.
  • 2,355
  • 5
  • 32
  • 43