C# 基于当前用户的“角色”动态构建 ASP.NET MVC 母版页菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2203320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:23:10  来源:igfitidea点击:

Building an ASP.NET MVC Master Page Menu Dynamically, Based on the current User's "Role"

c#.netasp.netasp.net-mvcsecurity

提问by Nate

I've seen some similar questions, but none that look like what I'm trying to do.

我见过一些类似的问题,但没有一个看起来像我想要做的。

This is my current implementation w/out any security:

这是我当前的实现,没有任何安全性:

<div id="menucontainer">
    <ul id="menu">              
        <li><%= Html.ActionLink("Main List", "Index", "AController")%></li>
        <li><%= Html.ActionLink("Product List", "Index", "BController")%></li>
        <li><%= Html.ActionLink("Company List", "Index", "CController")%></li>
        <li><%= Html.ActionLink("User List", "Index", "DController")%></li>
    </ul>
</div>

This is fine, and the above works. I have [Authorize] Attributes setup on the Actions for CController and DController to prevent unauthorized access -- but I'd like to remove those items from the menu for users who don't have the correct Role, because when they see it and click on it and it tells them they don't have permission, they'll want it. If they don't know it's there, that's just better for everyone involved...

这很好,上面的工作。我在 CController 和 DController 的 Actions 上设置了 [Authorize] 属性以防止未经授权的访问——但我想从菜单中为没有正确角色的用户删除这些项目,因为当他们看到并单击时在它上面,它告诉他们他们没有许可,他们会想要它。如果他们不知道它在那里,那对每个参与者都更好......

Something like this is ultimately the goal I'm trying to get at, but I'm looking for the more MVC Flavored aproach, where the "view" is "dumb":

这样的事情最终是我想要达到的目标,但我正在寻找更多 MVC 风味的方法,其中“视图”是“愚蠢的”:

<div id="menucontainer">
    <ul id="menu">              
        <li><%= Html.ActionLink("Main List", "Index", "AController")%></li>
        <li><%= Html.ActionLink("Product List", "Index", "BController")%></li>
        <% If(Role = Roles.Admin) { %>
        <li><%= Html.ActionLink("Company List", "Index", "CController")%></li>
        <li><%= Html.ActionLink("User List", "Index", "DController")%></li>
        <% } %>
    </ul>
</div>

采纳答案by jeroenh

I have done something like this:

我做了这样的事情:

  • use a common base class for my controllers ('layer supertype')
  • in the BaseController, override OnActionExecuted (you could also define an ActionFilter attribute for this)
  • 为我的控制器使用一个公共基类(“层超类型”)
  • 在 BaseController 中,覆盖 OnActionExecuted(您也可以为此定义 ActionFilter 属性)

Something like this:

像这样的东西:

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // build list of menu items based on user's permissions, and add it to ViewData
        IEnumerable<MenuItem> menu = BuildMenu(); 
        ViewData["Menu"] = menu;
    }

In the master page:

在母版页中:

    <% var model = ViewData["Menu"] as IEnumerable<MenuItem>; %>
    <% Html.RenderPartial("Menu", model); %>

(Note: in reality, I have a MasterViewModel that contains among others the menu model)

(注意:实际上,我有一个 MasterViewModel,其中包含菜单模型)

回答by Fitzchak Yitzchaki

Did you hear about MvcContrib's MenuBuilder?

你听说过MvcContrib的 MenuBuilder 吗?

If not, I suggest you take a look at it. The example project UIis a good way to start learning how to use it.

如果没有,我建议你看看它。示例项目UI是开始学习如何使用它的好方法。

回答by Billy Coover

Like @SD" said, you can create a "shiny" helper that with either render the link, or not, based on your security requirement.

就像@SD”所说的那样,您可以创建一个“闪亮”的助手,根据您的安全要求,要么呈现链接,要么不呈现链接。

Here is a good read on custom helpers (towards the bottom):

这是关于自定义助手的好读物(朝向底部):

understanding-html-helpers on S. Walther's blog

S. Walther 博客上的理解-html-helpers

回答by lopezbertoni

Usually I just check the role in a similar way you did and then either render a partial view with the links or just create them. Something like this using Razor syntax. I use T4MVC for actions.

通常我只是以与您类似的方式检查角色,然后使用链接呈现局部视图或仅创建它们。像这样使用 Razor 语法。我使用 T4MVC 进行操作。

@if(User.IsInRole("Admin"))
{
    <li><a href="@Url.Action(MVC.Admin.User.Index())">Users</a></li>
}

For security I use Fluent Security. Hope this helps.

为了安全,我使用 Fluent Security。希望这可以帮助。

回答by Joe

Nobody's mentioned MvcSiteMapProviderwhich does this and can be easily integrated into your Visual Studio project using NuGet.

没有人提到MvcSiteMapProvider可以做到这一点,并且可以使用 NuGet 轻松集成到您的 Visual Studio 项目中。

回答by Azerax

Joe's solution by far was the simplest and worked for me. I have pages present in separate areas for which I need to quickly setup a menu system that reacts and works based on which area the user is present in. Also in my case there are no cross-area links in my system, so am going to next configure multiple sitemaps for the MvcSiteMapProvider.

到目前为止,乔的解决方案是最简单的并且对我有用。我的页面存在于不同的区域,我需要快速设置一个菜单系统,该系统根据用户所在的区域做出反应和工作。此外,在我的情况下,我的系统中没有跨区域链接,所以我打算接下来为 MvcSiteMapProvider 配置多个站点地图

Hope this helps anyone else looking for a simple and effective solution!

希望这可以帮助其他人寻找简单有效的解决方案!