2016-05-17 4 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

Yea - あなたが意味することは分かっています。問題は、ユーザーが特定のアクション/コントローラに結びついているだけでなく、メニューに必要なリンクを作成させることです。 – William

+0

私は欲張りのキャプチャを使った正規表現を考えています可能な限り多くの文字がマッチします)(@ itsme86で言及されているように、ルートテーブルの使用など、他のすべての可能な選択肢は無視されます)。 –

答えて

0

私たちのコードでも同様のことがあります。私たちのマスターページには左側にメニューがありますが、1つのメニュー項目は一連のサブページに関連付けることができます。

私たちが行った解決策は、各メニュー項目が正規表現のリストを保持することでした。

コードのスニペットをたくさん用意します。これは、このビルダーは、動的に再構築します

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

(メソッドUrlMatchPatternに気づく)私たちは、Builderパターンを使用して、当社のメニューを定義する自己完結型のソリューションではありませんが、あなたのアイデアを与える可能性があり...

各ページ要求のメニュー、ナビゲーションパネルのノードの束生成:

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

前述のように、私たちのマッチングロジックは正規表現によるものです。 もちろん、このエンドユーザを設定可能にする場合は、一致するロジックを設定する必要があります。どのようにこれを行うのか分かりません。作成しているユーザーインターフェイスによって異なります。

関連する問題