2013-10-28 23 views
3

可以說我有地圖如何使用mvcsitemapprovider呈現特有的站點地圖部分

<mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" > 
     <mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="MenuHelper,!*"> 
      <mvcSiteMapNode title="T1" controller="Home" action="T1" /> 
      <mvcSiteMapNode title="T2" controller="Home" action="T2"/> 
     </mvcSiteMapNode> 
     <mvcSiteMapNode title="Help" controller="Help" action="Index"> 
      <mvcSiteMapNode title="T1" controller="Help" action="T1" /> 
      <mvcSiteMapNode title="T2" controller="Help" action="T2" /> 
      <mvcSiteMapNode title="T3" controller="Help" action="T3" /> 
      <mvcSiteMapNode title="T4" controller="Help" action="T4" /> 
      <mvcSiteMapNode title="T5" controller="Help" action="T5" /> 
      <mvcSiteMapNode title="T6" controller="Help" action="T6" /> 
     </mvcSiteMapNode> 
</mvcSiteMapNode> 

@Html.MvcSiteMap().Menu()將顯示的菜單包含上述 節點,但可以說,在我希望顯示來自網站地圖只有特定的節點頁腳,可以說我想要顯示節點Help

<ul> 
    <li> 
    <a href="/help"> 
    </li> 
    <li> 
    <a href="/help/t1">T1</a> 
    </li> 
    <li> 
    <a href="/help/t2">T2</a> 
    </li> 
    //and so on.... 
    </ul> 

我該怎麼做?

我猜我可能需要創建一個自定義模板,但我如何傳遞一個字符串值到自定義模板?

回答

3

選項1

這樣做的一種方法是明確設置起始節點。首先,給起始節點的明確重點:

<mvcSiteMapNode title="Help" controller="Help" action="Index" key="HelpKey"> 
    <mvcSiteMapNode title="T1" controller="Help" action="T1" /> 
    <mvcSiteMapNode title="T2" controller="Help" action="T2" /> 
    <mvcSiteMapNode title="T3" controller="Help" action="T3" /> 
    <mvcSiteMapNode title="T4" controller="Help" action="T4" /> 
    <mvcSiteMapNode title="T5" controller="Help" action="T5" /> 
    <mvcSiteMapNode title="T6" controller="Help" action="T6" /> 
</mvcSiteMapNode> 

並使用菜單過載:

@Html.MvcSiteMap().Menu(Html.MvcSiteMap().SiteMap.FindSiteMapNodeFromKey("HelpKey"), false, false) 

但做這種方式不會給你太多的控制。

選項2

您還可以使用自定義可見性提供程序。你可以通過自定義數據使用sourceMetaData字典知名度提供商,所以您可以創建一個單獨的「名稱」爲每個菜單例如:

@Html.MvcSiteMap().Menu(new { name = "MainMenu" }) 
@Html.MvcSiteMap().Menu(new { name = "HelpMenu" }) 

然後自定義的知名度提供商可以使用FilteredSiteMapNodeVisibilityProvider使用您的相同的邏輯自定義「名稱」屬性:

/// <summary> 
/// Filtered SiteMapNode Visibility Provider for use with named controls. 
/// 
/// Rules are parsed left-to-right, first match wins. Asterisk can be used to match any control or any control name. Exclamation mark can be used to negate a match. 
/// </summary> 
public class CustomFilteredSiteMapNodeVisibilityProvider 
    : SiteMapNodeVisibilityProviderBase 
{ 
    #region ISiteMapNodeVisibilityProvider Members 

    /// <summary> 
    /// Determines whether the node is visible. 
    /// </summary> 
    /// <param name="node">The node.</param> 
    /// <param name="sourceMetadata">The source metadata.</param> 
    /// <returns> 
    ///  <c>true</c> if the specified node is visible; otherwise, <c>false</c>. 
    /// </returns> 
    public override bool IsVisible(ISiteMapNode node, IDictionary<string, object> sourceMetadata) 
    { 
     // Is a visibility attribute specified? 
     string visibility = string.Empty; 
     if (node.Attributes.ContainsKey("visibility")) 
     { 
      visibility = node.Attributes["visibility"].GetType().Equals(typeof(string)) ? node.Attributes["visibility"].ToString() : string.Empty; 
     } 
     if (string.IsNullOrEmpty(visibility)) 
     { 
      return true; 
     } 
     visibility = visibility.Trim(); 

     // Check for the source HtmlHelper 
     if (sourceMetadata["HtmlHelper"] == null) 
     { 
      return true; 
     } 
     string htmlHelper = sourceMetadata["HtmlHelper"].ToString(); 
     htmlHelper = htmlHelper.Substring(htmlHelper.LastIndexOf(".") + 1); 

     string name = sourceMetadata["name"].ToString(); 

     // All set. Now parse the visibility variable. 
     foreach (string visibilityKeyword in visibility.Split(new[] { ',', ';' })) 
     { 
      if (visibilityKeyword == htmlHelper || visibilityKeyword == name || visibilityKeyword == "*") 
      { 
       return true; 
      } 
      else if (visibilityKeyword == "!" + htmlHelper || visibilityKeyword == "!" + name || visibilityKeyword == "!*") 
      { 
       return false; 
      } 
     } 

     // Still nothing? Then it's OK! 
     return true; 
    } 

    #endregion 
} 

然後更新您的配置以使用名稱而不是控件類型。

<mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" > 
     <mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="MainMenu,!*"> 
      <mvcSiteMapNode title="T1" controller="Home" action="T1" /> 
      <mvcSiteMapNode title="T2" controller="Home" action="T2"/> 
     </mvcSiteMapNode> 
     <mvcSiteMapNode title="Help" controller="Help" action="Index" visibility="HelpMenu,!*"> 
      <mvcSiteMapNode title="T1" controller="Help" action="T1" /> 
      <mvcSiteMapNode title="T2" controller="Help" action="T2" /> 
      <mvcSiteMapNode title="T3" controller="Help" action="T3" /> 
      <mvcSiteMapNode title="T4" controller="Help" action="T4" /> 
      <mvcSiteMapNode title="T5" controller="Help" action="T5" /> 
      <mvcSiteMapNode title="T6" controller="Help" action="T6" /> 
     </mvcSiteMapNode> 
</mvcSiteMapNode> 

並且不要忘記將您的自定義可見性提供程序設置爲您的配置中的默認值。

使用內部DI(web.config中):

<appSettings> 
    <add key="MvcSiteMapProvider_DefaultSiteMapNodeVisibiltyProvider" value="MyNamespace.CustomFilteredSiteMapNodeVisibilityProvider, MyAssemblyName"/> 
</appSettings> 

使用外部DI(在DI模塊 - 顯示Ninject爲例):

this.Kernel.Bind<ISiteMapNodeVisibilityProviderStrategy>().To<SiteMapNodeVisibilityProviderStrategy>() 
    .WithConstructorArgument("defaultProviderName", "MyNamespace.CustomFilteredSiteMapNodeVisibilityProvider, MyAssemblyName"); 

注:如果你需要一個切換父節點的可見性關閉,但保留子節點可見,則應使用Menu(),SiteMap()或SiteMapPath()的重載之一,以允許您將visibleAffectsDescendants參數設置爲false。這是默認情況下。

+0

選項1對我來說最簡單! –

相關問題