kacalapy
kacalapy

Reputation: 10134

Can I hide/show asp:Menu items based on role?

Am I able to hide certain menu items in an asp:Menu control based on role?

<asp:Menu ID="mTopMenu" runat="server" Orientation="Horizontal" />
    <Items>
        <asp:MenuItem Text="File">
            <asp:MenuItem Text="New Project" />
            <asp:MenuItem Text="Release Template" NavigateUrl="~/Release/ReleaseTemplate.aspx" />
            <asp:MenuItem Text="Release Schedule" NavigateUrl="~/Release/ReleaseSchedule.aspx" />
            <asp:MenuItem Text="Roles" NavigateUrl="~/Admin/AdminRoles.aspx" />
        </asp:MenuItem>
    </Items>
</asp:Menu>

How can I make one of these items visible to only users in the Admin role? I am using asp.net role provider.

Upvotes: 32

Views: 125562

Answers (10)

Arun Prasad E S
Arun Prasad E S

Reputation: 10115

SIMPLE method may not be the best for all cases

        <%                
            if (Session["Utype"].ToString() == "1")
            {
        %>
        <li><a href="../forms/student.aspx"><i class="fa fa-users"></i><span>STUDENT DETAILS</span></a></li>   
        <li><a href="../forms/UserManage.aspx"><i class="fa fa-user-plus"></i><span>USER MANAGEMENT</span></a></li>
        <%
              }
            else
             {
        %>                      
        <li><a href="../forms/Package.aspx"><i class="fa fa-object-group"></i><span>PACKAGE</span></a></li>
        <%
             }                
        %>

Upvotes: 3

Ian Boyd
Ian Boyd

Reputation: 256581

To remove a MenuItem from an ASP.net NavigationMenu by Value:

public static void RemoveMenuItemByValue(MenuItemCollection items, String value)
{
   MenuItem itemToRemove = null;

   //Breadth first, look in the collection
   foreach (MenuItem item in items)
   {
      if (item.Value == value)
      {
          itemToRemove = item;
          break;
      }
   }

   if (itemToRemove != null)
   {
      items.Remove(itemToRemove);
      return;
   }


   //Search children
   foreach (MenuItem item in items)
   {
       RemoveMenuItemByValue(item.ChildItems, value);
   }
}

and helper extension:

public static RemoveMenuItemByValue(this NavigationMenu menu, String value)
{
   RemoveMenuItemByValue(menu.Items, value);
}

and sample usage:

navigationMenu.RemoveMenuItemByValue("UnitTests");

Note: Any code is released into the public domain. No attribution required.

Upvotes: 1

DanLents
DanLents

Reputation: 21

I have my menu in the site master page. I used the Page_Load() function to make the "Admin" menu item only visible to users with an Admin role.

using System;
using System.Linq;
using Telerik.Web.UI;
using System.Web.Security;



<telerik:RadMenu ID="menu" runat="server" RenderMode="Auto"  >
    <Items>
       <telerik:RadMenuItem    Text="Admin"  Visible="true" />
    </Items>
 </telerik:RadMenu>

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        RadMenuItem item = this.menu.FindItemByText("Admin");
        if (null != item)
        {
            if (Roles.IsUserInRole("Admin"))
            {
                item.Visible = true;   
            }
            else
            {
                item.Visible = false;
            }
        }
    }
}

Upvotes: 1

Carmine Pacifico
Carmine Pacifico

Reputation: 21

Try this:

protected void Menu1_DataBound(object sender, EventArgs e)
{
   recursiveMenuVisit(Menu1.Items);
}

private void recursiveMenuVisit(MenuItemCollection items)
        {
            MenuItem[] itemsToRemove = new MenuItem[items.Count];
            int i = 0;

            foreach (MenuItem item in items)
            {
                if (item.NavigateUrl.Contains("Contact.aspx"))
                {
                    itemsToRemove[i] = item;
                    i++;
                }
                else
                {
                    if (item.ChildItems.Count > 0) recursiveMenuVisit(item.ChildItems);
                }
            }

            for(int j=0; j < i; j++)
            {
                items.Remove(itemsToRemove[j]);
            }
        }

Upvotes: 2

Terence Golla
Terence Golla

Reputation: 1189

This is best done in the MenuItemDataBound.

protected void NavigationMenu_MenuItemDataBound(object sender, MenuEventArgs e)
{
    if (!Page.User.IsInRole("Admin"))
    {
        if (e.Item.NavigateUrl.Equals("/admin"))
        {
            if (e.Item.Parent != null)
            {
                MenuItem menu = e.Item.Parent;

                menu.ChildItems.Remove(e.Item);
            }
            else
            {
                Menu menu = (Menu)sender;

                menu.Items.Remove(e.Item);
            }               
        }
    }
}

Because the example used the NavigateUrl it is not language specific and works on sites with localized site maps.

Upvotes: 9

Dipen
Dipen

Reputation: 1064

To find menu items in content page base on roles

 protected void Page_Load(object sender, EventArgs e)
{
   if (Session["AdminSuccess"] != null)
        {
           Menu mainMenu = (Menu)Page.Master.FindControl("NavigationMenu");

    //you must know the index of items to be removed first
    mainMenu.Items.RemoveAt(1);

    //or you try to hide menu and list items inside menu with css 
    // cssclass must be defined in style tag in .aspx page
    mainMenu.CssClass = ".hide";

        }   

}

<style type="text/css">
.hide
    {
        visibility: hidden;
     }
  </style>  

Upvotes: 0

Brian
Brian

Reputation: 1

You just have to remove the parent menu in the page init event.

    Protected Sub navMenu_Init(sender As Object, e As System.EventArgs) Handles navMenu.Init
    'Remove the admin menu for the norms
    Dim cUser As Boolean = HttpContext.Current.User.IsInRole("Admin")

    'If user is not in the Admin role removes the 1st menu at index 0
    If cUser = False Then
        navMenu.Items.RemoveAt(0)
    End If
End Sub

Upvotes: 0

BMASolutions
BMASolutions

Reputation: 211

I prefer to use the FindItem method and use the value path for locating the item. Make sure your PathSeparator property on the menu matches what you're using in FindItem parameter.

    protected void Page_Load(object sender, EventArgs e)
    {

        // remove manage user accounts menu item for non-admin users.
        if (!Page.User.IsInRole("Admin"))
        {
            MenuItem item = NavigationMenu.FindItem("Users/Manage Accounts");
            item.Parent.ChildItems.Remove(item);  
        }

    }

Upvotes: 14

Jon Hallin
Jon Hallin

Reputation: 508

You can remove unwanted menu items in Page_Load, like this:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Roles.IsUserInRole("Admin"))
        {
            MenuItemCollection menuItems = mTopMenu.Items;
            MenuItem adminItem = new MenuItem();
            foreach (MenuItem menuItem in menuItems)
            {
                if (menuItem.Text == "Roles")
                    adminItem = menuItem;
            }
            menuItems.Remove(adminItem);
        }
    }

I'm sure there's a neater way to find the right item to remove, but this one works. You could also add all the wanted menu items in a Page_Load method, instead of adding them in the markup.

Upvotes: 28

theChrisKent
theChrisKent

Reputation: 15099

You can bind the menu items to a site map and use the roles attribute. You will need to enable Security Trimming in your Web.Config to do this. This is the simplest way.

Site Navigation Overview: http://msdn.microsoft.com/en-us/library/e468hxky.aspx

Security Trimming Info: http://msdn.microsoft.com/en-us/library/ms178428.aspx

SiteMap Binding Info: http://www.w3schools.com/aspnet/aspnet_navigation.asp

Good Tutorial/Overview here: http://weblogs.asp.net/jgalloway/archive/2008/01/26/asp-net-menu-and-sitemap-security-trimming-plus-a-trick-for-when-your-menu-and-security-don-t-match-up.aspx

Another option that works, but is less ideal is to use the loginview control which can display controls based on role. This might be the quickest (but least flexible/performant) option. You can find a guide here: http://weblogs.asp.net/sukumarraju/archive/2010/07/28/role-based-authorization-using-loginview-control.aspx

Upvotes: 22

Related Questions