如何在 MVC 中处理基于角色的视图?
Posted
技术标签:
【中文标题】如何在 MVC 中处理基于角色的视图?【英文标题】:How to handle role-based views in MVC? 【发布时间】:2010-08-14 14:16:52 【问题描述】:无论使用何种语言或 MVC 框架,我应该如何处理基于角色的不同视图?
例如(伪代码):
查看/发布/显示:
<% show post here %>
if (role.isAdmin or role.isModerator)
<% show moderation tools %>
<% show rest of content %>
我不太喜欢将太多业务逻辑放入视图中的想法,但似乎没有其他选择。有吗?
一旦您拥有更多角色或不同级别的权限,这将变得越来越混乱。以这个网站为例。拥有超过 200 名代表的用户看到的广告较少。拥有超过 500 名代表的用户有一个重新标记按钮。然后你会在 2000 时获得一个编辑按钮,在 3000 时获得一个关闭按钮,在 10k 时获得审核工具,如果您是“明星”版主,则可以获得更多功能。
【问题讨论】:
【参考方案1】:您可以通过自定义 ViewModel 来使其更简洁一些,该 ViewModel 带有一个名为 ShowModerationTools
的布尔属性。在您的控制器中,您执行检查以查看当前用户是否可以根据他们的角色查看帖子并将ShowModerationTools
设置为true
或false
。然后,您将自定义 ViewModel 返回到视图。这样您就可以在您的视图中执行此操作:
<% show post here %>
if (Model.ShowModerationTools)
<% show moderation tools %>
<% show rest of content %>
这也意味着如果您的业务规则发生变化(例如您需要引入另一个条件),您只需更改控制器而不需要更改您的视图。
【讨论】:
【参考方案2】:这并没有错。这不是业务逻辑。这是表示逻辑。
if
回答的问题是:我们应该显示审核工具吗?
它不像:“普通用户是否应该能够删除整个付款历史记录”之类的。
【讨论】:
查看我更新的问题。您将如何处理多个或多级角色和权限? 然后将逻辑移至所谓的视图模型。在视图中您只需像if (ShowAds/CanRetag/CanEdit/CanClose/GotMoreTools) rendersomefilthyhtml();
一样检查它。或者为此使用所谓的助手。
这怎么不是业务逻辑?我认为 ACL 和工作流是业务逻辑的基本定义......这就是我们进入模糊区域的地方,业务逻辑和表示逻辑之间的差异缩小到几乎没有。表示逻辑是“我应该显示这个元素”,而不是“我什么时候应该显示这个元素”。 when 部分是业务逻辑(因此可以说不属于视图)...
@ircmaxell 您已经自己回答了问题。模型和控制器应该提供问题“何时”的答案。视图只是将其拾取并显示或隐藏某些内容。【参考方案3】:
我同意 Arnis L. - 但会添加以下内容。
你可以这样做...
<% show post here %>
<% Html.RenderAction<MyControllerName>(m => m.ModerationTools()); %>
<% show rest of content %>
这有几个好处。
它将审核工具所需的模型和视图封装在单个操作中。
这可能会让您不再需要在您作为示例发布的页面中的模型上扮演角色
它可以在其他页面上重复使用。
【讨论】:
封装可能会使事情变得更复杂。例如。 - 在这种情况下,视图模型将包含容器属性,该属性实际上是局部视图的视图模型。如果它只有 1 lvl 深,它就可以很好地工作,否则很快就会失控。 @Arnis L. 不确定您是否正确。视图模型将不包含 RenderAction 语句的数据。这就是 RenderAction 优于 RenderPartial 的全部意义 - RenderAction 调用具有自己独立模型的操作。【参考方案4】:就个人而言,我认为这里更重要的是好和足够好之间的区别......
虽然从技术上讲,我认为这归类为业务逻辑,但对于这样一个简单的案例,我认为将其包含在视图中没有问题。
现在,如果您有更复杂的逻辑,我建议为每个“逻辑分支”创建一个新视图,并在控制器中在它们之间进行选择。
【讨论】:
以上是关于如何在 MVC 中处理基于角色的视图?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 GetUsersInRoleAsync 方法检索角色中的所有用户并按照以下 .net Core MVC 中的实现将其显示在视图中