Asp.net mvc MVCSiteMapProvider面包屑未正确反向链接

Asp.net mvc MVCSiteMapProvider面包屑未正确反向链接,asp.net-mvc,asp.net-mvc-4,breadcrumbs,mvcsitemapprovider,Asp.net Mvc,Asp.net Mvc 4,Breadcrumbs,Mvcsitemapprovider,MVC站点地图提供程序版本4.6.18.0程序集版本 使用MVC4 我已经设置了站点地图,其中包含一些静态根节点和用于显示单个产品项的动态节点。为了简洁起见,我们假设有两种产品类型 1新娘 2珠宝 每个产品类型都有一个与之关联的带类型。 问题: 我在Mvc.sitemap中首先列出了Bridal,它似乎优先于面包屑显示,因此与面包屑相关的反向链接是不正确的 <mvcSiteMapNode title="Bridal" controller="Products" action="Br

MVC站点地图提供程序版本4.6.18.0程序集版本 使用MVC4

我已经设置了站点地图,其中包含一些静态根节点和用于显示单个产品项的动态节点。为了简洁起见,我们假设有两种产品类型

1新娘 2珠宝

每个产品类型都有一个与之关联的带类型。 问题: 我在Mvc.sitemap中首先列出了Bridal,它似乎优先于面包屑显示,因此与面包屑相关的反向链接是不正确的

    <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;
    }
}
我知道这一定是我忽略的简单的事情。任何帮助都会很好

为什么?

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>
就您的站点设计而言,如果您有某种方法来指示数据库中的主要类别,并进行适当的连接以确保正确设置了密钥和规范密钥,那么这将是最好的

我创建了一个只将规范密钥设置为BridalRings类别下的相应产品,这样您就可以看到它是如何完成的。请注意,如果您转到另一个类别下的产品列表并查看源代码,您将看到一个引用原始内容URL的规范标记

<link rel="canonical" href="http://localhost:64658/Products/BridalRings/Details/1" />
参考资料:

有两个问题。 1创建不同的路线,以清楚地识别@nightOwl888提供的示例应用程序中定义的产品类型。 2在站点地图定义中,有一个属性键必须是唯一的,因此我已经了解了。我使用该键定义子产品类型,当您有重复的子产品类型时,这将有冲突,并且第一个定义获胜

我是怎么解决的 1我创建了一个名为code的附加属性。此代码可以在整个站点地图中复制。这允许我为父类别传递重复的子类型


现在我有工作面包屑了

谢谢你的快速回复。这在演示中效果很好,我唯一能让它在我的演示中发挥作用的方法是,我在@Html.MvcSiteMap.SiteMap@Layout.cshtml页面中单击生成的链接。我在菜单系统中使用boostrap。用户导航到所需的产品页面并选择产品以查看更多详细信息。即使我在生成的页面中更改url以匹配有效的路径,我也不会得到任何碎屑。如果且仅当我使用站点地图链接时,它才会工作。我可以通过更改以下内容来解决此问题。1在我的产品页面中,我在我的网站地图中添加了独特的路线2,我使用该代码作为产品子类型的键。我添加了一个名为code的附加属性,现在我将其用于子产品类型,它允许我为每个动态节点定义不同的键。学习曲线。我感谢你的帮助。再次感谢
<link rel="canonical" href="http://localhost:64658/Products/BridalRings/Details/1" />