5

我已经为 webforms 应用程序回答了这个问题,但是我可以用这个代码隐藏我的管理菜单项吗?是否可以使用站点地图绑定或其他方式?

我的菜单在:Layout.cshtml

    <ul id="navlist">
        <li class="first"> <a href="@Url.Content("~")" id="current">Home</a> </li>

        <li>
            <a href="#">User</a>
            <ul class="second">
                <li> <a href="@Url.Content("~/Service/")">> Services</a></li>
            </ul>
        </li>

        <li> 
            <a href="#">Administration</a>
            <ul class="second">
                <li><a href="@Url.Content("~/ServiceManager")">> Services</a></li>
            </ul>
        </li>

        <li>@Html.Partial("_LogOnPartial") </li>
    </ul>
4

3 回答 3

7

如 Alternative 所述,使用简单 if 语句的适用性取决于:

- 你有多少角色(因为你可能希望通过避免多次查询来避免对数据库的多次查询

if(User.IsInRole("whatever"))

- 如果您使用自定义角色和成员资格提供程序,在这种情况下,您可能希望避免同时使用 User.IsInRole,因为它每次都会打开到数据库的新连接。

Brij Mohan Dammani描述了一个解决方案,它具有一些不错的功能,但我喜欢在视图中添加太多逻辑。在可能的面向对象语言中,我也更喜欢强类型对象。

基于 Brij Dammani 描述的代码,我现在使用一个模型:

namespace Whatever
{
  public class RoleMenuItem: MenuItem
  {
    public RoleMenuItem(){}
    public RoleMenuItem(string linkText, string actionName, string controllerName, string roleNames)
    {
        LinkText = linkText;
        ActionName = actionName;
        ControllerName = controllerName;
        RoleNames = roleNames;
    }
    public string RoleNames { set { Roles = value.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries); } }
    internal string[] Roles;
  }
  public class MenuItem
  {
    public string LinkText { get; set; }
    public string ActionName { get; set; }
    public string ControllerName { get; set; }
  }
  public class RoleMenu : System.Collections.Generic.IEnumerable<MenuItem>
  {
    private readonly List<RoleMenuItem> _roleMenuItems = new List<RoleMenuItem>();
    private readonly string[] _userRoleNames;
    public readonly bool _isAuthenticated;
    public RoleMenu()
    {
        if (_isAuthenticated = WebSecurity.User.Identity.IsAuthenticated)
        {
            _userRoleNames = Roles.GetRolesForUser();
        }
    }
    public RoleMenu(IDataContext context) 
    {
        if (_isAuthenticated = WebSecurity.User.Identity.IsAuthenticated)
        {
            string userName = HttpContext.Current.User.Identity.Name;
            User usr = context.Users.FirstOrDefault(Usr => Usr.UserName == userName) ;
            _userRoleNames = (usr==null)? new string[0]: usr.Roles.Select(r => r.RoleName).ToArray(); 

        }
    }
    public RoleMenu Add(RoleMenuItem menuItem)
    {
        string[] menuRoles = menuItem.Roles;
        if (
                menuRoles.Contains("All" ) ||
                (!_isAuthenticated && menuRoles.Contains("Anonymous")) ||
                (_isAuthenticated && (menuRoles.Contains("Authenticated") || menuRoles.Any(mr=>_userRoleNames.Contains(mr))))
            )
        {
            _roleMenuItems.Add(menuItem);
        }
        return this;
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public System.Collections.Generic.IEnumerator<MenuItem> GetEnumerator()
    {
        return _roleMenuItems.GetEnumerator();
    } 
    public IEnumerable<MenuItem> ItemsForRole(string roleName)
    {
        return _roleMenuItems.Where(r => r.Roles.Contains(roleName));
    }
}

然后在每个 Controller 的构造函数中(为依赖注入而设置)

ViewBag.Menu = new RoleMenu(_db);

并在 _Layout 视图中

@using WhateverNamespace
<nav>
    <ul id="menu">
    @{
       RoleMenu menu = (ViewBag.Menu ?? new RoleMenu())
          .Add(new RoleMenuItem("Home", "Index", "Home","Anonymous"))
          .Add(new RoleMenuItem("Home", "Auth", "Home","Authenticated"))
          .Add(new RoleMenuItem("About", "About", "Home","All"))
          .Add(new RoleMenuItem("Administer", "Index", "Administrators","Webmaster,Administrator"))...;
       foreach (var link in menu)
       {
          <li> 
              @Html.ActionLink(link.LinkText, link.ActionName,link.ControllerName)
            ....

或者

    if((var adminMenuItems=menu.ItemsFoRole("admin")).Any()) {
       <li><ul>
       foreach (var link in adminMenuItems) {
           <li> ....
       }
于 2012-09-15T03:26:22.557 回答
2

只需添加此 IF 条件即可正常工作。其中“管理员”是您要显示此菜单项的用户角色。

       @if(User.IsInRole("Administrator"))
           {

    <li>        
        <a href="#">Administration</a>       
        <ul class="second">       
            <li><a href="@Url.Content("~/ServiceManager")">> Services</a></li>       
        </ul>       
    </li>

        }
于 2012-07-31T13:33:10.460 回答
0

您可以使用它来根据用户角色显示或隐藏:

 @using Microsoft.AspNet.Identity
    @using Microsoft.AspNet.Identity.Owin;


    @if (Request.IsAuthenticated)
    {
        var userManager = Request.GetOwinContext().GetUserManager<IdentitySample.Models.ApplicationUserManager>();
        var userRoles = userManager.GetRoles(User.Identity.GetUserId());
        var role = userRoles[0]; 

   if (role == "Admin")
        {
           <p>Hello Admin!</p>

        }


   }`
于 2017-08-31T14:12:58.533 回答