片段由浏览器处理,但不会发回服务器,因此在使 URL 唯一时,它实际上并没有“计数”。因此,如果您有多个仅在片段上有所不同的节点,则 MvcSiteMapProvider 将无法区分它们,并且无论您选择哪个节点,它都会始终匹配第一个注册的节点。
这基本上意味着您的面包屑不会更改,并且选择替代片段时所选菜单项不会更改。这不是错误,只是无法做到。
但是,如果您出于导航以外的其他原因需要添加片段(例如 JavaScript 支持),您可以通过向节点添加自定义属性然后修改节点模板以在视图中输出片段来完成此操作.
首先,给节点添加一个自定义属性。
<mvcSiteMapNode title="Funds" controller="VcTransfer" action="Index" fragment="Network-tab">
然后确保将自定义属性的名称添加为要忽略的属性,否则它将作为查询字符串参数而不是片段出现在您的 URL 中。
内部 DI(根 web.config):
<appSettings>
<add key="MvcSiteMapProvider_AttributesToIgnore" value="fragment"/>
</appSettings>
外部 DI:
this.For<IReservedAttributeNameProvider>().Use<ReservedAttributeNameProvider>()
.Ctor<IEnumerable<string>>("attributesToIgnore").Is(new string[] { "fragment" });
然后修改你的/Views/Shared/DisplayTemplates/SiteMapNodeModel.cshtml文件如下图,当它存在于节点上时输出片段。
@model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models
@{
var fragment = (Model.Attributes["fragment"] != null) ? "#" + Model.Attributes["fragment"] : "";
var url = Model.Url + fragment;
}
@if (Model.IsCurrentNode && Model.SourceMetadata["HtmlHelper"].ToString() != "MvcSiteMapProvider.Web.Html.MenuHelper") {
<text>@Model.Title</text>
} else if (Model.IsClickable) {
if (string.IsNullOrEmpty(Model.Description))
{
<a href="@url">@Model.Title</a>
}
else
{
<a href="@url" title="@Model.Description">@Model.Title</a>
}
} else {
<text>@Model.Title</text>
}