MVC Sitemap Provider版本4.6.18.0(程序集版本) 使用MVC4
我已经设置了一些带有动态节点的静态根节点的站点地图,用于显示单个产品项目。为简洁起见,我们假设有两种产品类型
1)新娘 2)珠宝每种产品类型都有与之关联的Band类型。 问题: 我在Mvc.sitemap中首先列出了Bridal,它似乎优先于breadcrumb显示,因此相对于面包屑的反向链接不正确。
<mvcSiteMapNode title="Bridal" controller="Products" action="Bridal">
<mvcSiteMapNode title="Bands" controller="Products" action="BridalRings">
<mvcSiteMapNode title="Details" action="BridalRings" key="Bands" dynamicNodeProvider="Betteridge.Web.Services.ProductNodeProvider, Betteridge.Web" />
</mvcSiteMapNode>
<mvcSiteMapNode title="Engagement" controller="Products" action="BridalEngagement">
<mvcSiteMapNode title="Details" action="BridalEngagement" key="Engagement" dynamicNodeProvider="Betteridge.Web.Services.ProductNodeProvider, Betteridge.Web" />
</mvcSiteMapNode>
</mvcSiteMapNode>
<mvcSiteMapNode title="Jewelry" controller="Products" action="Jewelry">
<mvcSiteMapNode title="Bands" controller="Products" action="JewelryBands">
<mvcSiteMapNode title="Details" action="JewelryBands" key="Bands" dynamicNodeProvider="Betteridge.Web.Services.ProductNodeProvider, Betteridge.Web" />
</mvcSiteMapNode>
...
为什么?
这是我的动态节点提供程序代码。
public class ProductNodeProvider : DynamicNodeProviderBase
{
public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
{
string parent = "";
if(node.Attributes.ContainsKey("parentNode"))
{
parent = node.Attributes["parentNode"].ToString();
}
List<ProductModel> products = DataServices.GetActiveProductBySubType(parent,node.Key);
var returnValue = new List<DynamicNode>();
foreach (ProductModel p in products)
{
DynamicNode dnode = new DynamicNode();
dnode.Title = p.ProductName;
dnode.Action = "Details";
dnode.Controller = "Products";
dnode.RouteValues.Add("id", p.ProductId);
returnValue.Add(dnode);
}
return returnValue;
}
}
我知道这一定是我要忽视的简单事情。任何帮助都会很棒。
答案 0 :(得分:0)
为什么?
MvcSiteMapProvider
不支持具有相同路由值的多个节点。
您需要为其添加至少一个附加参数,以区分Bridal
下列出的产品与Jewelry
下列出的产品之间的区别。
最简单的方法是简单地将此信息添加到路线中。
routes.MapRoute(
name: "Category",
url: "{controller}/{category}/{action}/{id}"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
然后您只需要将category
参数添加到动态节点。最简单的方法是将其添加到XML中,它将自动作为路由值包含在提供者创建的每个动态节点中。
<mvcSiteMapNode title="Bridal" controller="Products" action="Bridal">
<mvcSiteMapNode title="Bands" controller="Products" action="BridalRings">
<mvcSiteMapNode title="Details" action="BridalRings" key="Bands" category="BridalRings" dynamicNodeProvider="Betteridge.Web.Services.ProductNodeProvider, Betteridge.Web" />
</mvcSiteMapNode>
<mvcSiteMapNode title="Engagement" controller="Products" action="BridalEngagement">
<mvcSiteMapNode title="Details" action="BridalEngagement" key="Engagement" category="BridalEngagement" dynamicNodeProvider="Betteridge.Web.Services.ProductNodeProvider, Betteridge.Web" />
</mvcSiteMapNode>
</mvcSiteMapNode>
<mvcSiteMapNode title="Jewelry" controller="Products" action="Jewelry">
<mvcSiteMapNode title="Bands" controller="Products" action="JewelryBands">
<mvcSiteMapNode title="Details" action="JewelryBands" key="Bands" category="JewelryBands" dynamicNodeProvider="Betteridge.Web.Services.ProductNodeProvider, Betteridge.Web" />
</mvcSiteMapNode>
</mvcSiteMapNode>
确实,将相同的内容放在2个不同的网址上是件坏事 - 也就是说,直到您添加canonical tag来指示哪一个是&#34;主要&#34;内容来源。这就是你可以向搜索引擎表明这是内容的故意副本。
MvcSiteMapProvider
只需指定canonicalKey
即可支持规范标记生成。您只需要确保有一个唯一的密钥给予&#34; master&#34;节点,然后对所有副本使用相同的密钥。
要启用规范密钥生成,您只需将CanonicalTag
HTML帮助器添加到_Layout.cshtml
页面(<head>
元素内)。
@Html.MvcSiteMap().CanonicalTag()
就您的网站设计而言,最好是您有某种方式来指明哪个类别是&#34;主要&#34;数据库中的一个,并执行适当的连接以确保正确设置密钥和规范密钥。
我创建了一个demo project,只是将规范键设置为BridalRings
类别下的相应产品,以便您可以看到它是如何完成的。请注意,如果您转到其他类别下的产品详情并查看来源,则会看到一个规范标记,其中包含对原始内容网址的引用。
<link rel="canonical" href="http://localhost:64658/Products/BridalRings/Details/1" />
参考:https://github.com/maartenba/MvcSiteMapProvider/wiki/Multiple-Navigation-Paths-to-a-Single-Page
答案 1 :(得分:0)
有两个问题。 1)创建不同的路径以清楚地识别由@ nightOwl888提供的示例应用程序中定义的产品类型。 2)在站点地图定义中有一个属性“key”,它必须是唯一的,所以我已经学会了。我使用密钥来定义子产品类型,当您有重复的子产品类型时,这将产生冲突并且第一个定义获胜。
我是如何解决这个问题的 1)我创建了一个名为code的附加属性。此代码可以在整个站点地图中重复。这允许我为父类别传递重复的子类型。
2)现在我在整个工作面包屑。