C# 处理从不同角色隐藏数据的最易维护的方法MVC

C# 处理从不同角色隐藏数据的最易维护的方法MVC,c#,asp.net-mvc,mvvm,asp.net-mvc-5,C#,Asp.net Mvc,Mvvm,Asp.net Mvc 5,情况: 目前我正在工作的一个项目有大约13个控制器,都有索引、摘要(转到索引的表视图)、创建、详细信息、编辑和删除视图。每个控制器都有自己的ViewModel 我最近加入了这个团队,并将这个复制粘贴项目更改为具有继承和接口的高度可维护项目 问题: 我刚刚开始研究视图,创建HTML帮助程序和类似的东西,以使视图更易于维护 我们的所有控制器操作都使用[Authorize(Roles=“…”)]属性。 索引视图采用这种设置样式(每个列表项都使用ViewModel的每个属性): 过滤段 表头 目录 表

情况

目前我正在工作的一个项目有大约13个控制器,都有索引、摘要(转到索引的表视图)、创建、详细信息、编辑和删除视图。每个控制器都有自己的ViewModel

我最近加入了这个团队,并将这个复制粘贴项目更改为具有继承和接口的高度可维护项目

问题

我刚刚开始研究视图,创建HTML帮助程序和类似的东西,以使视图更易于维护

我们的所有控制器操作都使用
[Authorize(Roles=“…”)]
属性。 索引视图采用这种设置样式(每个列表项都使用ViewModel的每个属性):

  • 过滤段
  • 表头
  • 目录
  • 表尾
其他人最初的想法是将
if(User.IsInRole(…)
放在每个适用的位置,即
if(User.IsInRole(…){@Html.DisplayFor(SomePropertyInFilterSection)}
和遵循模式
if(User.IsInRole(…){@Html.DisplayFor(SamePropertyInTableHeader)}
。 我认为这是一个巨大的混乱,但已经开始寻找使它更干净(4如果语句隐藏一个'单一'的数据似乎愚蠢。 我认为这是一个巨大的混乱,应该有一个更简单的方法来对所有这些if语句进行一次检查(因为它们检查的是同一件事,但在不同的位置)

选项

我看到的选项包括:

  • 在每个地方执行if语句
  • 有两个单独的视图,并在离开控制器之前进行检查
  • 将css类添加到每个数据段,并在主ViewModel上有一个标志(这是ViewModel所有ViewModel的继承源,因为它们都共享2-3个属性),并有一个JavaScript适当地隐藏/删除这些元素
据我所知,安全性不应该是一个问题,因为数据(目前)不敏感,任何可能被点击(恶意或无意)的链接都不应该有
[Authorize]
属性来解决这个问题

问题

实现这一点最容易维护的方法是什么

目前我对上述选项的看法:

  • 太乱了
  • 解决了If语句混乱的问题,但添加了一个需要维护的额外视图,如果一个内容发生了变化,那么另一个内容可能也会发生变化
  • 如果我们决定添加我们不希望未经正确授权的人看到的敏感数据,可能会成为一个问题

有没有什么办法能同时兼顾第二和第三两种情况呢?

我不相信有“正确”的说法答:很多人会键入你不应该考虑把if语句放在视图中的帽子,但是我们需要记住,作为专业的开发人员,我们为不遵循信条的航运产品而获得报酬。 我的建议是,对每个视图使用逐案方案中最好的方法。逻辑简单吗?将其放在一个视图中。它是否开始变得杂乱无章?创建单独的视图。大多数逻辑是否仅在一个位置?创建局部视图。在逐案方案中执行此操作还可以让您找出最适合您的项目的方法


不过,我建议不要使用基于JS或CSS的逻辑。这不仅关乎安全,而且你最终也会发送(有时会发送很多)当你决定你的数据实际上是敏感的,有一个很大的变化,你将无法100%地保护它。

我最后制作了一些HTML助手来帮助这个过程

public static MvcHtmlString IfRole(this MvcHtmlString content, HtmlHelper html, Role role)
{
    return html.ViewContext.HttpContext.User.IsInRole(Roles.ToString(role)) ? content : MvcHtmlString.Create(String.Empty);
}
这四条线路的所有部分:

@if (User.IsInRole(Role.ToString(Role.MyRole))
{
    @Html.TextBoxFor(....)
}
一行:

@Html.TextBoxFor(....).IfRole(Html, Role.MyRole)
此外,我还提出了一些帮助工具,尽可能地抽象出更多的内容(按钮、链接等),使它们成为一行。一些重复的“类似控件”的html模式也成为了帮助工具

对我有帮助的主要事情是我仍在考虑的一些事情。我在考虑在所有ViewModels上创建一个函数/接口,该函数/接口返回其所有属性的
字典
。然后为筛选器节、表头等创建一个HtmlHelper,以使用该数据构建数据。(我没有这么做的原因是,我只考虑这样做会让页面看起来很独特。尽管我认为最终我会这样做,并添加可选的
字典
参数来添加HtmlAttributes)


我希望这对将来的某个人有帮助,这花费了我(不合理地)很长一段时间,如果没有Mihai Andrei Dinclescu的想法,我可能无法得出这个结论。

我很困惑。如果要隐藏“单个”数据段的语句看起来很愚蠢,那么
4是什么意思?您需要4个
如果
语句呢?为什么控制器要将数据传递给您随后看到的视图“单一数据段”是一个属性,该属性在索引视图(筛选器、表头、表内容和表脚)上显示3-4次。这些位置中的每一个都需要类似于以下
if(User.IsInRole(…){}的if语句
。我意识到我在解释我的全部问题时做得不太好,所以我编辑了这个问题。你当前的答案没有完全回答,但很有帮助(特别是考虑到我在解释问题时做得不好,很抱歉).简单的澄清:我不是直接问别人在这种情况下我应该做什么,而是问是否有一个选项可以消除我的#2和#3选项的可维护性陷阱(或者如果有其他我不知道的选项)。我相信我的答案仍然是正确的