我們的代碼中有類似的東西。我們的母版頁面左側有一個菜單,但是一個菜單項目可以與一系列子頁面相關聯。
我們的解決方案是每個菜單項都包含一個正則表達式列表。
我會給你一些我們的代碼片段。這不是一個獨立的解決方案,但可能會給你的想法...
我們將使用生成器模式定義我們的菜單(注意方法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);
}
如前所述,我們的匹配邏輯是通過正則表達式。 當然,如果你讓這個最終用戶可配置,你將不得不讓他們配置匹配邏輯。我不知道你將如何做到這一點 - 這取決於你正在創建的用戶界面。
這看起來像是你在與MVC戰鬥。你爲什麼不用'Url.Action()'這樣的東西? – itsme86
是的 - 我知道你的意思 - 問題是我讓用戶在菜單上創建他們想要的任何鏈接 - 不僅僅是與特定動作/控制器綁定的東西 – William
我認爲正則表達式與貪婪捕獲(即嘗試匹配儘可能多的字符)將工作(忽略所有其他可能的替代方案,如使用路由表,如@ itsme86所述)。 – 2016-05-17 22:57:13