2016-05-17 61 views
0

這是一個有點抽象:ASP.NET - 確定選擇哪個菜單項

我有一個用ASP.NET MVC編寫的網站。最終用戶可以創建一個Menu對象,該對象將在站點菜單中移動。這看起來像這樣:

public class Menu 
{ 
    public string Caption { get; set; } 
    public string Address { get; set; } 

    public Menu(string Caption, string Address) 
    { 
     this.Caption = Caption; 
     this.Address = Address; 
    } 
} 

public Menu Menu1 = new("Home", "/"); 
public Menu Menu2 = new("Events", "/events"); 
public Menu Menu3 = new("Specific Event", "/event/13"); 

當請求進來時,我需要能夠確定哪個菜單項是「活動」。另外,如果請求是針對未明確命名的項目的「子頁面」,則該菜單項目也應該被標記爲激活的(例如,如果請求是針對「/ event/95/checkout」的,則Menu2將是標記爲活動)。

我在考慮將相對URL與URL的地址進行比較,以確定哪些字符匹配大多數字符,從字符串的開始處開始 - 但我該怎麼做呢?有沒有更好的方法?

+0

這看起來像是你在與MVC戰鬥。你爲什麼不用'Url.Action()'這樣的東西? – itsme86

+0

是的 - 我知道你的意思 - 問題是我讓用戶在菜單上創建他們想要的任何鏈接 - 不僅僅是與特定動作/控制器綁定的東西 – William

+0

我認爲正則表達式與貪婪捕獲(即嘗試匹配儘可能多的字符)將工作(忽略所有其他可能的替代方案,如使用路由表,如@ itsme86所述)。 – 2016-05-17 22:57:13

回答

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); 
    } 

如前所述,我們的匹配邏輯是通過正則表達式。 當然,如果你讓這個最終用戶可配置,你將不得不讓他們配置匹配邏輯。我不知道你將如何做到這一點 - 這取決於你正在創建的用戶界面。

相關問題