Puis-je masquer certains éléments de menu dans un contrôle asp:Menu
en fonction du rôle?
<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>
Comment rendre l'un de ces éléments visible uniquement aux utilisateurs du rôle Admin? J'utilise le fournisseur de rôle asp.net.
Vous pouvez lier les éléments de menu à un plan de site et utiliser l'attribut roles. Pour ce faire, vous devez activer le filtrage de sécurité dans votre Web.Config. C'est le moyen le plus simple.
Présentation de la navigation dans le site: http://msdn.Microsoft.com/en-us/library/e468hxky.aspx
Informations de suppression de sécurité: http://msdn.Microsoft.com/en-us/library/ms178428.aspx
Informations de liaison de SiteMap: http://www.w3schools.com/aspnet/aspnet_navigation.asp
Bon tutoriel/Vue d'ensemble ici: http://weblogs.asp.net/jgalloway/archive/2008/01/26/asp-net-menu-and-sitemap-security-trimming-plus-a- astuce pour-quand-votre-menu-et-la-sécurité-ne-t-match-up.aspx
Une autre option qui fonctionne mais qui est moins idéale consiste à utiliser le contrôle loginview, qui peut afficher des contrôles en fonction du rôle. Cette option est peut-être la plus rapide (mais la moins flexible/performante). Vous pouvez trouver un guide ici: http://weblogs.asp.net/sukumarraju/archive/2010/07/28/role-based-authorization-using-loginview-control.aspx
Vous pouvez supprimer les éléments de menu non désirés dans Page_Load, comme ceci:
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);
}
}
Je suis sûr qu'il existe un moyen plus astucieux de trouver le bon élément à supprimer, mais celui-ci fonctionne. Vous pouvez également ajouter tous les éléments de menu souhaités dans une méthode Page_Load, au lieu de les ajouter dans le balisage.
Je préfère utiliser la méthode FindItem et utiliser le chemin de valeur pour localiser l'élément. Assurez-vous que votre propriété PathSeparator du menu correspond à ce que vous utilisez dans le paramètre 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);
}
}
Cela se fait mieux dans 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);
}
}
}
}
Comme l'exemple utilisé NavigateUrl, il n'est pas spécifique à la langue et fonctionne sur les sites contenant des cartes de site localisées.
La méthode SIMPLE peut ne pas être la meilleure dans tous les cas
<%
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>
<%
}
%>
Essaye ça:
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]);
}
}
Pour supprimer une MenuItem
d'un fichier ASP.net NavigationMenu
parValue
:
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);
}
}
et extension d'assistance:
public static RemoveMenuItemByValue(this NavigationMenu menu, String value)
{
RemoveMenuItemByValue(menu.Items, value);
}
et exemple d'utilisation:
navigationMenu.RemoveMenuItemByValue("UnitTests");
Remarque : Tout code est publié dans le domaine public. Aucune attribution requise.
J'ai mon menu dans la page principale du site. J'ai utilisé la fonction Page_Load () pour que l'élément de menu "Admin" ne soit visible que par les utilisateurs dotés d'un rôle Admin.
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;
}
}
}
}
Pour rechercher des éléments de menu dans la base de pages de contenu sur des rôles
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>
Il vous suffit de supprimer le menu parent dans l'événement init de la page.
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