简体   繁体   English

MVC4 Bootstrap示例中基于角色的导航显示

[英]Role-based navigation display in MVC4 Bootstrap Sample

How are you supposed to conditionally display menu items based on roles in the Bootstrap Sample project? 您应该如何根据Bootstrap Sample项目中的角色有条件地显示菜单项? I was thinking of doing the following 我在想做以下事情

  1. Implement INavigatonRouteFilter - really just implementing the shouldRemove(Route navigationRoutes) method - by getting the default controller/action for the route and seeing if the user is authorized 实现INavigatonRouteFilter实际上只是实现shouldRemove(Route navigationRoutes)方法-通过获取shouldRemove(Route navigationRoutes)的默认控制器/操作并查看用户是否获得授权
  2. Call NavigationRoutes.Filters.Add(myAuthorizationFilter) after configuring the NavigationRoutes in App_Start App_Start配置NavigationRoutes之后,调用NavigationRoutes.Filters.Add(myAuthorizationFilter) App_Start

There are two problems I see with this approach: 我看到这种方法有两个问题:

  1. I don't actually know how to do the first step unless I add in a bunch of conditional statements to check for Controller 's name explicitly 除非我添加一堆条件语句来显式检查Controller的名称,否则我实际上不知道如何执行第一步
  2. This seems like it could make NavigationRoutes.Filters very hard to deal with once there are a lot of filters or a desire for more modularity later on 似乎这会使NavigationRoutes.Filters变得非常难处理,一旦存在大量过滤器或稍后需要更多的模块化

I don't know that I've explained the problem clearly enough, but basically I want to use what is provided in the Bootstrap sample to implement authorization-based navigation menu display if at all possible. 我不知道我已经足够清楚地解释了这个问题,但是基本上,我想尽可能使用Bootstrap示例中提供的内容来实现基于授权的导航菜单显示。 Using INavigationRouteFilter just seemed like the most natural way to do so. 使用INavigationRouteFilter似乎是最自然的方法。

For those looking for an answer or at least a quick fix. 对于那些寻找答案或至少是快速解决方案的人。 Here's what I've come up with after 5 minutes and I most certainly haven't though about any side effects this may have. 这是我在5分钟后得出的结论,但我肯定没有任何副作用。

routes.MapNavigationRoute<HomeController>("Index", c => c.Index())
            .FilterRoute(() => !WebSecurity.IsAuthenticated);

You can either do all your filtering in your call to FilterRoute() or you can add more extension methods to save you some characters. 您可以在对FilterRoute()的调用中进行所有过滤,也可以添加更多扩展方法来节省一些字符。

I'm thinking of .RequireRole("Adiministrators"); 我在想.RequireRole(“ Adiministrators”); that calls WebSecurity.RequireRoles() in turn (or HttpContext.Current.User.IsInRole()) etc. 依次调用WebSecurity.RequireRoles()(或HttpContext.Current.User.IsInRole())等。

public static NavigationRouteBuilder FilterRoute(this NavigationRouteBuilder builder, Func<bool> func)
    {
        var currentRoute = builder._parent;

        NavigationRoutes.Filters.Add(new BootstrapAuthorizationFilter(builder, x => 
        {
            if (x == currentRoute)
                return func();
            else
                return false;
        }));

        return builder;
    }

and BootstrapAuthorizationFilter is just a class implementing INavigationRouteFilter that calls func() in its ShouldRemove() method 和BootstrapAuthorizationFilter只是实现INavigationRouteFilter的类,该类在其ShouldRemove()方法中调用func()

public class BootstrapAuthorizationFilter : INavigationRouteFilter
{
    private NavigationRouteBuilder builder;
    private Func<NamedRoute, bool> func;

    public BootstrapAuthorizationFilter(NavigationRouteBuilder builder, Func<NamedRoute, bool> func)
    {
        this.builder = builder;
        this.func = func;
    }

    public bool ShouldRemove(Route navigationRoutes)
    {
        if (navigationRoutes is NamedRoute)
            return func(navigationRoutes as NamedRoute);

        return false;
    }
}

Clearly nothing fancy and I'm not sure if I'd use it in production. 显然没有花哨,我不确定是否要在生产中使用它。 But I think is simple enough and works (for the cases I tested). 但是我认为这很简单并且可以工作(针对我测试过的情况)。 Having said that, I hope the new routing functionality is going to be released soon :) 话虽如此,我希望新的路由功能将很快发布:)

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

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