简体   繁体   English

基于当前用户的“角色”动态构建ASP.NET MVC主页面菜单

[英]Building an ASP.NET MVC Master Page Menu Dynamically, Based on the current User's “Role”

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. 我在Actions for CController和DController上设置[授权]属性以防止未经授权的访问 - 但是我想从菜单中删除那些没有正确角色的用户,因为当他们看到它并点击时在它上面它告诉他们他们没有许可,他们会想要它。 If they don't know it's there, that's just better for everyone involved... 如果他们不知道那里,那对所有参与者来说都更好......

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>

I have done something like this: 我做过这样的事情:

  • use a common base class for my controllers ('layer supertype') 为我的控制器使用公共基类('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,其中包含菜单模型)

没有人提到过MvcSiteMapProvider ,它可以使用NuGet轻松集成到Visual Studio项目中。

Did you hear about MvcContrib 's MenuBuilder? 你听说过MvcContrib的MenuBuilder吗?

If not, I suggest you take a look at it. 如果没有,我建议你看一下。 The example project UI is a good way to start learning how to use it. 示例项目UI是开始学习如何使用它的好方法。

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. 使用Razor语法这样的东西。 I use T4MVC for actions. 我使用T4MVC进行操作。

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

For security I use Fluent Security. 为了安全起见,我使用了Fluent Security。 Hope this helps. 希望这可以帮助。

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! 希望这可以帮助其他人寻找简单有效的解决方案!

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM