5

この質問は Web フォーム アプリで既に回答済みですが、このコードで管理メニュー項目を非表示にできますか? サイトマップのバインディングなどで可能ですか?

私のメニュー: 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));
    }
}

次に、各コントローラーのコンストラクター(依存性注入用に設定されています)

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 に答える