这有点抽象:
我有一个用ASP.NET MVC编写的网站。最终用户可以创建一个Menu对象,该对象将在站点的菜单中移位。这看起来像这样:
$rootScope
当请求进入时,我需要能够确定哪个菜单项是“活动”。此外,如果请求是针对未明确命名的项目的“子页面”,则菜单项也应标记为活动(例如,如果请求是“/ event / 95 / checkout”,则Menu2将是标记为有效。)
我正在考虑尝试将相对URL与URL的地址进行比较,以确定哪些匹配最多的字符,从字符串的开头开始 - 但我该如何去做呢?还有更好的方法吗?
答案 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);
}
如上所述,我们的匹配逻辑是通过正则表达式。 当然,如果您要让这个最终用户可配置,您必须让他们配置匹配逻辑。我不知道你将如何做到这一点 - 这取决于你正在创建的用户界面。