我可以根据角色隐藏/显示 asp:Menu 项吗?

Posted

技术标签:

【中文标题】我可以根据角色隐藏/显示 asp:Menu 项吗?【英文标题】:Can I hide/show asp:Menu items based on role? 【发布时间】:2011-06-23 18:24:26 【问题描述】:

我能否根据角色隐藏asp:Menu 控件中的某些菜单项?

<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>

如何使这些项目之一仅对具有管理员角色的用户可见? 我正在使用 asp.net 角色提供程序。

【问题讨论】:

【参考方案1】:

您可以将菜单项绑定到站点地图并使用角色属性。您需要在您的 Web.Config 中启用 Security Trimming 才能执行此操作。这是最简单的方法。

网站导航概述: http://msdn.microsoft.com/en-us/library/e468hxky.aspx

安全修整信息: http://msdn.microsoft.com/en-us/library/ms178428.aspx

站点地图绑定信息: http://www.w3schools.com/aspnet/aspnet_navigation.asp

这里有很好的教程/概述: 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

另一个可行但不太理想的选项是使用 loginview 控件,该控件可以根据角色显示控件。这可能是最快(但最不灵活/性能)的选项。您可以在这里找到指南:http://weblogs.asp.net/sukumarraju/archive/2010/07/28/role-based-authorization-using-loginview-control.aspx

【讨论】:

【参考方案2】:

您可以在 Page_Load 中删除不需要的菜单项,如下所示:

    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);
        
    

我确信有一种更简洁的方法可以找到要删除的正确项目,但这个方法很有效。您还可以在 Page_Load 方法中添加所有需要的菜单项,而不是在标记中添加它们。

【讨论】:

【参考方案3】:

我更喜欢使用 FindItem 方法并使用值路径来定位项目。确保菜单上的 PathSeparator 属性与您在 FindItem 参数中使用的属性相匹配。

    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);  
        

    

【讨论】:

您可能应该在 Menu 的 DataBound 事件中而不是在 Page_Load 中执行上述操作,因为 DataBound 事件将在每次数据绑定到菜单时运行,这可能发生在 Page_Load 之后。【参考方案4】:

您只需在页面初始化事件中删除父菜单。

    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

【讨论】:

【参考方案5】:

Value 从 ASP.net NavigationMenu 中删除 MenuItem

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);
   

和辅助扩展:

public static RemoveMenuItemByValue(this NavigationMenu menu, String value)

   RemoveMenuItemByValue(menu.Items, value);

和示例用法:

navigationMenu.RemoveMenuItemByValue("UnitTests");

注意:任何代码都会发布到公共领域。无需署名。

【讨论】:

【参考方案6】:

根据角色在内容页面中查找菜单项

 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>  

【讨论】:

【参考方案7】:

这最好在 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);
                           
        
    

由于该示例使用了 NavigateUrl,因此它不是特定于语言的,并且适用于具有本地化站点地图的站点。

【讨论】:

【参考方案8】:

试试这个:

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]);
            
        

【讨论】:

【参考方案9】:

我在站点母版页中有我的菜单。我使用 Page_Load() 函数使“管理员”菜单项仅对具有管理员角色的用户可见。

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;
            
        
    

【讨论】:

但这是一个 Telerik 控件,而不是原生 asp.net 控件!【参考方案10】:

简单的方法可能并不适用于所有情况

        <%                
            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>
        <%
                             
        %>

【讨论】:

把这个放在aspx页面的html

以上是关于我可以根据角色隐藏/显示 asp:Menu 项吗?的主要内容,如果未能解决你的问题,请参考以下文章

根据用户角色隐藏导航栏

根据用户角色获取登录用户的django权限以显示/隐藏菜单

PHP 根据WordPress中的用户角色显示/隐藏内容

在WordPress中根据用户角色显示/隐藏内容

根据用户角色在仪表板上显示项目

根据用户角色隐藏一些 React 组件子项