0

I'm creating an ASP.NET MVC4 application which has a left menu panel, and the right main panel will be the content panel. (@RenderBody)

The links on the menu are generated based on the login role of the user. E.g., users with higher access will see more links on the menu. These access rights are stored in the database.

I have a _Layout.cshtml page which all my pages inherit from.

How should I code my access menu such that the access is retrieved only from the database once, during login? There after, every page the user navigates to, I won't have to re-query the database for his access rights.

Should I use Html.RenderAction or Html.Partial for my access menu page?

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
Null Reference
  • 11,260
  • 40
  • 107
  • 184

3 Answers3

0

You can define a partial view called 'Navigation.cshtml' in the Shared folder. And in your _Layout.cshtml, you can make a call like

<div id="left-menu">
   @Html.Partial("Navigation")
</div>

and your Navigation.cshtml should look like

@if(Request.IsAuthenticated) {
  // show links for authenticated user.
}
else {
 // show links for non-authenticated user.  
}
Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281
0

Your idea with RenderAction look's logically correct. Just add OutputCache with VaryByCustom, where you can check role and do not access database for each page and user.

Links that will help you:

Community
  • 1
  • 1
webdeveloper
  • 17,174
  • 3
  • 48
  • 47
0

I'd say the easiest way to do this is to use MVCSiteMapProvider which you can add to your project using NuGet.

It has an option securityTrimmingEnabled which will automatically remove items the user isn't authorized to see from the site map and hence from the menu.

How should I code my access menu such that the access is retrieved only from the database once, during login?

You should get your roles using a RoleProvider. If you have your own database schema for roles, you may need to write a custom role provider. The custom role provider can implement caching to avoid hitting the database too often, or, as long as there aren't too many roles, you can use the CacheRolesInCookie property.

Then put an Authorize attribute on Controllers and Actions that should be secured:

[Authorize(Roles="SomeRole")]
public ActionResult MyAction()
{
    ...
}
Joe
  • 122,218
  • 32
  • 205
  • 338
  • Can I avoid using hardcoded Roles="SomeRoles", because in my system, the admin can add more roles. – Null Reference Oct 30 '12 at 08:22
  • One way would be to create a custom authorize attribute: http://msdn.microsoft.com/en-us/library/ee707357(v=vs.91).aspx. – Joe Oct 30 '12 at 09:31