【问题标题】:Can I hide/show asp:Menu items based on role?我可以根据角色隐藏/显示 asp:Menu 项吗?
【发布时间】: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 角色提供程序。

【问题讨论】:

    标签: asp.net roles


    【解决方案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端
                  猜你喜欢
                  • 2017-12-13
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-04-15
                  • 1970-01-01
                  • 2012-12-14
                  • 1970-01-01
                  • 2011-02-25
                  • 1970-01-01
                  相关资源
                  最近更新 更多