如何根据角色显示或隐藏控件 - ASP.NET MVC 4 Razor

17

我正在开发ASP.NET MVC 4应用程序。 我有一个控制面板,我的用户组将基于Windows域,因此我使用Windows身份验证来验证用户。

我创建了一些示例应用程序,使用重写AuthorizeAttribute,ActionFilterAttribute函数的自定义身份验证。这是一个好方法吗?

  1. 哪种属性最适合用于身份验证?

我有一个控制面板。 因此,我需要根据角色显示或隐藏控件。 假设有三个网格(表格),如果管理员登录,他可以看到3个网格(表格)。但是,如果支持用户登录,他只能看到2个网格(表格)。

我的计划是为每个网格创建部分视图,所以每个部分视图都将有一个操作和控制器。 将有一个数据库,并在其中指定每个组可以执行的操作。 这样我就可以过滤请求。

2 如何根据角色隐藏或显示部分视图?

我尝试了一些SO 链接,但它们都是针对2,3个角色并且进行硬编码的。 在我的情况下,角色可能会有所不同,我们使用db设置角色的访问权限。

提前致谢。


控制器/操作注释在这里似乎不是很合适,您需要在创建视图模型的服务/层中进行逻辑检查。 - Tommy
那你能怎么做呢?可以请你提供更多的细节吗?我对MVC还不熟悉。 - kbvishnu
你所询问的问题比较广泛,但你很可能需要做类似这样的事情:如果(user.role == "admin"){ //填充所有模型网格 },如果(user.role == "guest"){ //只填充他们可以看到的网格,其他为空}。然后在你的视图中,如果(@model.grid!= null){输出数据}。 - Tommy
但是我如何为每个角色制作If条件呢?假设我有20个角色,我需要检查如果这是role1,否则是role2等等?还有其他解决方案吗? - kbvishnu
你提出了一些非常广泛的问题,任何答案都会非常通用。你可以将其拆分为多个函数/视图等,你可以使用if/then/else语句,有很多方法可供选择。很抱歉无法提供更多帮助。 - Tommy
@Tommy,感谢你的帮助。谢谢你提供的建议:“你需要在创建视图模型的服务/层中进行逻辑检查。” - kbvishnu
3个回答

22
您可以使用以下代码进行基于角色的检查。
@if(Request.IsAuthenticated)

{
    if(User.IsInRole("Admin"))
    {
     <Ul Class="SubMenuItem">

     <li> this menu item is for Admin role</li>
     </Ul>
    }
     if(User.IsInRole("User"))
    {
     <Ul Class="SubMenuItem">

     <li> this menu item is for User role</li>
     </Ul>
    }
}
@* For unknown user *@
else
{
     <Ul Class="SubMenuItem">
         <li> this menu item is for Unknown user</li>
     </Ul>
}

我在使用User.IsInRole时遇到了一个奇怪的问题,出现了“无法连接到SQL Server数据库”的错误。我通过在控制器上添加[InitializeSimpleMembership]来解决它。更多讨论请参见: https://dev59.com/cuo6XIcBkEYKwwoYORwV - RamblerToning
3
这并不真正回答这个问题。当你只有少量角色时,这是一个可以接受的解决方案,但问题明确说明:“我尝试了一些SO链接,但它们都在讨论2、3个角色,而且是硬编码的。 在我的情况下,角色可能会有所变化,我们使用数据库设置角色访问权限。” - Adrian Edwards

13
通常情况下,您希望保持视图尽可能清晰,没有逻辑。建议将角色检查逻辑移动到控制器操作中,并根据用户角色呈现部分视图。
您可以使用ChildActions和Html.Action扩展方法将其连接起来。
来自MSDN:
子操作方法呈现视图的一部分内联HTML标记,而不是呈现整个视图。任何标有ChildActionOnlyAttribute的方法只能通过Action或RenderAction HTML扩展方法调用。
在您的项目中,创建一个名为Dashboard的新控制器,并添加一个名为BuildTable的单个操作。
public class DashboardController : Controller
{
    [ChildActionOnly]
    public ActionResult BuildTable()
    {
        if (Roles.IsUserInRole("Administrator"))
        {
            return PartialView("_AdminTable");
        }

        return PartialView("_SupportTable");
    }
}

在您想要仪表板表格出现的视图中,包含以下行。
@Html.Action("BuildTable", "Dashboard")

6

我已经做过类似的事情。我所采用的方法(可能不是最好的方法)

是将一个布尔值发送回视图

在控制器中使用:

bool showSection1 = true;
bool showSection2 = false;

ViewData["showSection1"] = showSection1;
ViewData["showSection2"] = showSection2;
/// may be better to use a viewmodel here rather than ViewData

然后在视图中:
@if((bool)ViewData["showSection1"])
{
    @{Html.RenderPartial("section1");}
}
@if((bool)ViewData["showSection2"))
{
    @{Html.RenderPartial("Section2");}
}

您需要编写逻辑来设置布尔值,以使它们按您的意愿运行,但这应该是一个开始。

您还可以创建一个静态方法来返回角色,然后直接从视图中获取该值。但这可能不是最好的方式。

@if(AppHelper.GetRole().equals("role1")){
    //show the partial
}

然后创建一个名为AppHelper的类和一个名为GetRole的方法,该方法返回用户的角色。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接