Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to hide tabs based on roles defined in attributes in MVC3?

In a default install of a MVC3 website tabs are created in the top left. I would like to hide/show these tabs based on whether the current user would have access to the index ViewResult. The allowed roles to the ViewResult are defined by attributes. Is there any way of getting the list of roles for a ViewResult?

like image 979
Dale Avatar asked Sep 02 '11 16:09

Dale


1 Answers

If you are asking (sorry, wasn't clear exactly to me) about conditional showing of HTML elements based on roles, you could do something like this:

@if (User.IsInRole("Administrators"))
{
   @Html.ActionLink("Do Some Action", "DoAction", "SomeController")
}

If that isn't what you're asking, let me know.


Follow-up based on your comment:

Your question interests me and I did a little poking around and found that Vivien Chevallier has an interesting idea here which essentially lets you write something like so:

@Html.ActionLinkAuthorized("The Privilege Zone", "ThePrivilegeZone", "Home", true)

in your View and then this check the controller action and either renders a link or doesn't.

In his controller example, you've got an action like this:

[Authorize(Roles = "Administrator")]
public ActionResult ThePrivilegeZone()
{
    return View();
}

(I guess the key point here is that your View doesn't know squat about "Administrators" and relies upon the extension code to do the heavy lifting here:

public static MvcHtmlString ActionLinkAuthorized(
   this HtmlHelper htmlHelper, 
   string linkText, string actionName, string controllerName, 
   RouteValueDictionary routeValues, 
   IDictionary<string, object> htmlAttributes, bool showActionLinkAsDisabled)
{
   if (htmlHelper.ActionAuthorized(actionName, controllerName))
   {
      return htmlHelper.ActionLink(
         linkText, 
         actionName, controllerName, routeValues, htmlAttributes);
   }
   else
   {
      if (showActionLinkAsDisabled)
      {
         TagBuilder tagBuilder = new TagBuilder("span");
         tagBuilder.InnerHtml = linkText;
         return MvcHtmlString.Create(tagBuilder.ToString());
      }
      else
      {
         return MvcHtmlString.Empty;
      }
   }
}

Rather than cut/paste all of that code here, you can take a look at it and see the example application he's got for that. I think what's particularly interesting to this approach is that the view could display that PrivilegeZone link but knows only that something else will determine whether that's the case. So, assuming that you got new requirements to only allow folks who were "Administrators" or "Owners" to have access to the link, you could modify the controller action accordingly and not touch the view code. Interesting idea, at least to me.

like image 185
itsmatt Avatar answered Nov 11 '22 21:11

itsmatt