ASP.NET - 确定选择了哪个菜单项

时间:2016-05-17 21:54:00

标签: c# asp.net

这有点抽象:

我有一个用ASP.NET MVC编写的网站。最终用户可以创建一个Menu对象,该对象将在站点的菜单中移位。这看起来像这样:

$rootScope

当请求进入时,我需要能够确定哪个菜单项是“活动”。此外,如果请求是针对未明确命名的项目的“子页面”,则菜单项也应标记为活动(例如,如果请求是“/ event / 95 / checkout”,则Menu2将是标记为有效。)

我正在考虑尝试将相对URL与URL的地址进行比较,以确定哪些匹配最多的字符,从字符串的开头开始 - 但我该如何去做呢?还有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我们的代码中有类似的东西。我们的母版页左侧有一个菜单,但是一个菜单项可以与一系列子页面相关联。

我们使用的解决方案是为每个菜单项保存正则表达式列表。

我会给你一堆我们代码的片段。这不是一个独立的解决方案,但可能会给你一些想法......

我们将使用构建器模式定义我们的菜单(注意方法UrlMatchPattern

var builder = new SiteMapBuilder();
builder.Add
       .Title("Home")
       .LaunchUrl("~/Home/Index")
       .IconUrl("~/Images/menuIcons/home.png")
       .UrlMatchPattern("~/Home/Index/?.*"); 
builder.Add
        .Title("Network")
        .IconUrl("~/Images/menuIcons/network.png")
        .Children(b => 
                    {
                        b.Add.Title("Companies")
                            .LaunchUrl("~/Company")
                            .UrlMatchPattern("~/Company");
                        b.Add.Title("Groups")
                            .LaunchUrl("~/PlayerGroup")
                            .UrlMatchPattern("~/PlayerGroup")
                            .LimitToRoles(
                                            CmsUserRoleId.Administrators, 
                                            CmsUserRoleId.Support
                                          );
                        b.Add.Title("Players")
                            .LaunchUrl("~/Player/index")
                            .UrlMatchPattern(
                                                @"~/\bPlayer\b", 
                                                "~/Player/Index", 
                                                @"~/Admin/PlayerDiagnostics\.aspx"
                                            ); 

此构建器将动态重建每个页面请求的菜单,生成一组导航面板节点:

     internal NavPanelNode GenerateNode(IWebContext webContext, ...)
     {
            return new NavPanelNode
            {
                Title = _title,
                Url = _url,
                Children = _childNodeBuilder == null ? Enumerable.Empty<NavPanelNode>() : _childNodeBuilder.GenerateNodeHierachy(webContext, userContext),
                IsSelected = _urlMatchPattern.Any(pattern => webContext.MatchesPath(pattern)),
                IconUrl = _iconUrl
            };
   }

我的MatchesPath方法:

    public static bool MatchesPath(this IWebContext webContext, System.Text.RegularExpressions.Regex matchPattern)
    {
        string appRelativePath = webContext.CurrentRequestContext.GetAppRelativePath();
        return matchPattern.IsMatch(appRelativePath);
    }

如上所述,我们的匹配逻辑是通过正则表达式。 当然,如果您要让这个最终用户可配置,您必须让他们配置匹配逻辑。我不知道你将如何做到这一点 - 这取决于你正在创建的用户界面。