Asp.net mvc 3 基于安全性的ASP.NETMVC隐藏/显示菜单项

Asp.net mvc 3 基于安全性的ASP.NETMVC隐藏/显示菜单项,asp.net-mvc-3,asp.net-membership,Asp.net Mvc 3,Asp.net Membership,我正在一个ASP.NETMVC3网站上工作。_Layout master视图包含一个菜单,我想根据您是否登录以及您所处的角色隐藏菜单中的一些项目 目前,它使用类似这样的代码工作 @if (HttpContext.Current.User.Identity.IsAuthenticated) { <li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li>

我正在一个ASP.NETMVC3网站上工作。_Layout master视图包含一个菜单,我想根据您是否登录以及您所处的角色隐藏菜单中的一些项目

目前,它使用类似这样的代码工作

@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
   <li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> 
   if (HttpContext.Current.User.IsInRole("Reporters"))
   {
      <li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>
   }
   if (HttpContext.Current.User.IsInRole("Administrators"))
   {
      <li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>
      <li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li> 
   }
}
@if ((bool)ViewData["MenuMyLearning"]){<li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> }    
@if((bool)ViewData["MenuReports"]){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>}
@if ((bool)ViewData["MenuDashboard"]){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>}
@if ((bool)ViewData["MenuAdmin"]){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>}
public static bool DashboardVisible
{
   get 
   { 
      return 
         HttpContext.Current.User != null && 
         HttpContext.Current.User.Identity.IsAuthenticated; 
   }
}
@if (MenuSecurity.ReportsVisible){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>}
@if (MenuSecurity.DashboardVisible){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>}
@if (MenuSecurity.AdminVisible){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>}
然而,在生命周期的这一点上,用户对象是空的。我还尝试创建一个自定义全局过滤器,但是ViewData是不可访问的


这样做的推荐方法是什么?我是否应该让视图中的所有HttpContext代码保持最初的状态?

下面是我最后要做的。我为每个菜单项创建了一个名为MenuSecurity的助手类,该类具有静态布尔属性,显示哪些项应该可见。每个属性都是这样的

@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
   <li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> 
   if (HttpContext.Current.User.IsInRole("Reporters"))
   {
      <li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>
   }
   if (HttpContext.Current.User.IsInRole("Administrators"))
   {
      <li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>
      <li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li> 
   }
}
@if ((bool)ViewData["MenuMyLearning"]){<li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> }    
@if((bool)ViewData["MenuReports"]){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>}
@if ((bool)ViewData["MenuDashboard"]){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>}
@if ((bool)ViewData["MenuAdmin"]){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>}
public static bool DashboardVisible
{
   get 
   { 
      return 
         HttpContext.Current.User != null && 
         HttpContext.Current.User.Identity.IsAuthenticated; 
   }
}
@if (MenuSecurity.ReportsVisible){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>}
@if (MenuSecurity.DashboardVisible){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>}
@if (MenuSecurity.AdminVisible){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>}
然后我整理了一下菜单的局部视图,使其看起来像这样

@if (HttpContext.Current.User.Identity.IsAuthenticated)
{
   <li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> 
   if (HttpContext.Current.User.IsInRole("Reporters"))
   {
      <li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>
   }
   if (HttpContext.Current.User.IsInRole("Administrators"))
   {
      <li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>
      <li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li> 
   }
}
@if ((bool)ViewData["MenuMyLearning"]){<li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> }    
@if((bool)ViewData["MenuReports"]){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>}
@if ((bool)ViewData["MenuDashboard"]){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>}
@if ((bool)ViewData["MenuAdmin"]){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>}
public static bool DashboardVisible
{
   get 
   { 
      return 
         HttpContext.Current.User != null && 
         HttpContext.Current.User.Identity.IsAuthenticated; 
   }
}
@if (MenuSecurity.ReportsVisible){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>}
@if (MenuSecurity.DashboardVisible){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>}
@if (MenuSecurity.AdminVisible){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>}
@if(MenuSecurity.ReportsVisible){
  • @Html.ActionLink(“报告”、“索引”、“报告”)
  • } @if(MenuSecurity.DashboardVisible){
  • @Html.ActionLink(“Dashboard”、“Dashboard”、“Admin”)
  • } @if(MenuSecurity.AdminVisible){
  • @Html.ActionLink(“Admin”、“Index”、“Admin”)
  • }
    关于角色的一般建议

    我这样做的方式是创建一个自定义主体,并在其中存储所需的额外信息。在您的示例中,这至少包括用户的角色。这样可以避免对用户存储(可能是SQL数据库)进行大量额外的访问

    看看我的这个问题,我在其中给出了我正在成功使用的代码:

    请注意,我将自定义主体存储在缓存中,而不是会话中(只是对会话劫持心存疑虑)

    我喜欢这种方法,因为它具有很强的可扩展性。例如,我已经扩展了它,当用户通过Facebook登录时公开Facebook凭据

    只要记住,如果您正在缓存数据,则需要记住在数据更改时对其进行更新

    回答您的问题

    另外,在您的特定情况下,您可能应该将这些额外信息存储在
    ViewModel
    中,然后您的视图会显示如下内容:

    @if(ShowReports) { <li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li> }
    @if(ShowDashboard) { <li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li> }
    @if(ShowAdmin { <li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li> }
    
    实际上,我倾向于更进一步,在我的
    ViewModel
    中创建一个
    ReportsLink
    ,并将其设置为在用户获得授权时包含链接,或者在用户未获得授权时将其设置为空字符串。然后这个观点就说:

    @Model.ReportsLink
    @Model.DashboardLink
    @Model.AdminLink
    
    在这种情况下,ViewModel的相关部分可能如下所示:

    ReportLink = new MvcHtmlString(HtmlHelper.GenerateLink(HttpContext.Current.Request.RequestContext, System.Web.Routing.RouteTable.Routes, "linktext", "routename", "actionname", "controllername", null, null));
    

    创建局部视图并从控制器返回视图:

    LayoutViewModel.cs:

    public class LayoutViewModel
    {   ...
        public bool ShowAdmin { get; set; }
    }
    
    LayoutController.cs:

    public PartialViewResult GetAdminMenu()
        {
            LayoutViewModel model = new LayoutViewModel();            
    
            model.ShowAdmin = userHasPermission("Admin"); // change the code here
    
            return PartialView("_AdminMenu", model);
        }
    
    _AdminMenu.cshtml(部分视图):


    我想你只有3组。但是如果你有20-30个小组会发生什么呢?这里是另一个解决方案