Asp.net mvc 4 如何使用mvcsitemapprovider呈现特定的站点地图部分
假设我有网站地图Asp.net mvc 4 如何使用mvcsitemapprovider呈现特定的站点地图部分,asp.net-mvc-4,mvcsitemapprovider,Asp.net Mvc 4,Mvcsitemapprovider,假设我有网站地图 <mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" > <mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="MenuHelper,!*"> <mvcSiteMapNode title="T1"
<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>
我该怎么做
我猜我可能需要创建一个自定义模板,但如何将字符串值传递给自定义模板?选项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>
但是这样做并不能给你太多的控制权
选择2
也可以使用自定义可见性提供程序。您可以使用sourceMetaData字典将自定义数据传递给可见性提供程序,以便为每个菜单实例创建单独的“名称”:
@Html.MvcSiteMap().Menu(new { name = "MainMenu" })
@Html.MvcSiteMap().Menu(new { name = "HelpMenu" })
然后,自定义可见性提供程序可以使用FilteredItemsNodeVisibilityProvider用于自定义“name”属性的相同逻辑:
/// <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
}
//
///用于命名控件的筛选SiteMapNode可见性提供程序。
///
///规则从左到右解析,第一场比赛获胜。星号可用于匹配任何控件或任何控件名称。感叹号可用于否定匹配项。
///
公共类CustomFilteredItemsNodeVisibilityProvider
:SiteMapNodeVisibilityProviderBase
{
#区域IsItemaNodeVisibilityProvider成员
///
///确定节点是否可见。
///
///节点。
///源元数据。
///
///如果指定的节点可见,则为true;否则为false。
///
public override bool IsVisible(IsItemaNode节点,IDictionary sourceMetadata)
{
//是否指定了可见性属性?
字符串可见性=string.Empty;
if(node.Attributes.ContainsKey(“可见性”))
{
visibility=node.Attributes[“visibility”].GetType()等于(typeof(string))?node.Attributes[“visibility”].ToString():string.Empty;
}
if(string.IsNullOrEmpty(可见性))
{
返回true;
}
可见性=可见性.Trim();
//检查源HtmlHelper
if(sourceMetadata[“HtmlHelper”]==null)
{
返回true;
}
字符串htmlHelper=sourceMetadata[“htmlHelper”].ToString();
htmlHelper=htmlHelper.Substring(htmlHelper.LastIndexOf(“.”+1);
string name=sourceMetadata[“name”].ToString();
//全部设置。现在解析可见性变量。
foreach(visibility.Split中的字符串visibilityKeyword(新[]{',',';'}))
{
如果(visibilityKeyword==htmlHelper | | visibilityKeyword==name | | visibilityKeyword==“*”)
{
返回true;
}
否则如果(visibilityKeyword==“!”+htmlHelper | | visibilityKeyword==“!”+name | | visibilityKeyword==“!*”)
{
返回false;
}
}
//还是没什么?那就没事了!
返回true;
}
#端区
}
然后更新配置以使用名称而不是控件类型
<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):
使用外部DI(在DI模块中-所示为Ninject示例):
this.Kernel.Bind().To()
.WithConstructorArgument(“defaultProviderName”、“MyNamespace.CustomFilteredItemsNodeVisibilityProvider、MyAssemblyName”);
注意:如果需要关闭父节点的可见性,但保持子节点可见,则应使用Menu()、SiteMap()或SiteMapPath()的重载之一,以便将VisibilityAffectsDescents参数设置为false。默认情况下是这样。选项1对我来说是最简单的实现!
/// <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>
<appSettings>
<add key="MvcSiteMapProvider_DefaultSiteMapNodeVisibiltyProvider" value="MyNamespace.CustomFilteredSiteMapNodeVisibilityProvider, MyAssemblyName"/>
</appSettings>
this.Kernel.Bind<ISiteMapNodeVisibilityProviderStrategy>().To<SiteMapNodeVisibilityProviderStrategy>()
.WithConstructorArgument("defaultProviderName", "MyNamespace.CustomFilteredSiteMapNodeVisibilityProvider, MyAssemblyName");