mvcSiteMap 在 mvc 5 中创建 bredcrumb

mvcSiteMap create bredcrumb in mvc 5

我写信给你有一个问题。我有方法:

namespace NESTshop.Infrastructure
{
    public class ProductListDynamicNodeProvider : DynamicNodeProviderBase
    {
    private ApplicationDbContext db = new ApplicationDbContext();

    public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            var returnValue = new List<DynamicNode>();
            foreach (Category c in db.Category)
            {
            DynamicNode n = new DynamicNode();
            n.Title = c.CategoryTitle;
            n.Key = "Kategoria_" + c.CategoryID;

            returnValue.Add(n);
        }
        return returnValue;
    }
}

它应该给我面包屑(类别列表)。

我从类别中做了部分视图,因为我的主页上有类别列表。

模特类别:

namespace NESTshop.Models
{
    public class Category
    {
        [Key]
        public int CategoryID { get; set; }

        [Display(Name ="Nazwa kategorii")]
        public string CategoryTitle { get; set; }

        [Display(Name ="Opis kategorii")]
        public string CategoryDescription { get; set; }

        [Display(Name = "Ikona Kategorii")]
        public byte[] CategoryFile { get; set; }

        [HiddenInput(DisplayValue = false)]
        public string ImageMimeType { get; set; }

        public virtual ICollection<Product> Product { get; set; }
    }
}

部分查看产品类别

@using NESTshop.Models
@model List<Category>

<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <p><a href="http://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
</div>

<div class="row">
    <div class="col-md-12">
        <h2>Kategorie</h2>
        <ul class="categories">
            @foreach (var cat in Model)
            {
                <li>
                    <img width="30" height="30"
                         src="@Url.Action("GetImage", "Categories", new { cat.CategoryID })" />
                    @*<img src="@Url.Content("~/Content/Images/Categories/" + cat.CategoryFile)" alt="" width="30" heigth="30"/>*@
                    @Html.ActionLink(cat.CategoryTitle, "ProductCategory", "Products", new { CategoryID = cat.CategoryID }, null)
                </li>
            }
        </ul>
    </div>

</div>

HomeController 操作类别列表:

public ActionResult CategoriesList()
        {
            List<Category> categories = categoryRepo.GetCategory().ToList();

            return PartialView(categories);
        }

我在 ProductCategory 视图中显示:

@using NESTshop.Models
@using NESTshop.Infrastructure
@model List<Product>

@{
    ViewBag.Title = "ProductCategory";
}

@Html.MvcSiteMap().SiteMapPath() <--------

@if (User.IsInRole("Administrator"))
{
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
}
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.FirstOrDefault().ProductTitle)
        </th>
        @if (User.IsInRole("Administrator"))
        {
            <th>
                @Html.DisplayNameFor(model => model.FirstOrDefault().ProductDescription)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstOrDefault().DateAdded)
            </th>
        }
        <th>
            @Html.DisplayNameFor(model => model.FirstOrDefault().ProductFile)
        </th>

        <th>
            @Html.DisplayNameFor(model => model.FirstOrDefault().Price)
        </th>
        @if (User.IsInRole("Administrator"))
        {
            <th>
                @Html.DisplayNameFor(model => model.FirstOrDefault().IsBestseller)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstOrDefault().IsHidden)
            </th>
        }
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.ActionLink(Model.FirstOrDefault().ProductTitle, "Details", new { id = item.ProductID })
            </td>
            @if (User.IsInRole("Administrator"))
            {
                <td>
                    @Html.DisplayFor(modelItem => item.ProductDescription)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.DateAdded)
                </td>
            }
            <td>
                @Html.DisplayFor(modelItem => item.ProductFile)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            @if (User.IsInRole("Administrator"))
            {
                <td>
                    @Html.DisplayFor(modelItem => item.IsBestseller)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.IsHidden)
                </td>


                <td>

                    @Html.ActionLink("Edit", "Edit", new { id = item.ProductID }) |
                    @Html.ActionLink("Delete", "Delete", new { id = item.ProductID })
                </td>
            }
        </tr>
    }

</table>

问题之一,当我点击主页上的类别(测试类别 1)时,我得到了很好的面包屑(开始 > 测试类别 1),但是当我点击 2,3,4....类别 i具有相同的面包屑(开始 > 测试类别 1)。

你能帮我解决这个问题吗?非常感谢!

MVC 路由

面包屑基于当前节点。当前节点由当前请求的路由值决定。

因此您首先需要确保路由设置正确,以便将值作为路由值读入请求(与查询字符串值不同)。

路线选项 1

对所有主键使用 "id"。这是最简单的选项,因为默认路由是您唯一需要的。但是您需要确保构建您的 URL 和操作方法以使用 "id" 而不是 "CategoryID" 或 "ProductID".

 @Html.ActionLink(cat.CategoryTitle, "ProductCategory", "Products", new { id = cat.CategoryID }, null)

路线选项 2

更改路由以考虑使用其他 "id" 值。这确保您的 URL 构建为路径的一部分 (/Products/ProductCategory/1234) 而不是查询字符串的一部分 (/Products/ProductCategory?CategoryID=1234)。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
          name: "Category",
          url: "Products/ProductCategory/{CategoryID}",
          defaults: new { controller = "Products", action = "ProductCategory" }

        routes.MapRoute(
          name: "Product",
          url: "Products/{action}/{ProductID}",
          defaults: new { controller = "Products", action = "Index" }

        routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
      );
    }
}

动态节点提供者

您在动态节点提供程序中负责两件事:

  1. 您必须为节点提供所有路由值才能创建与当前请求的匹配项
  2. 如果您有嵌套数据,则必须显式提供键-父键映射

ProductListDynamicNodeProvider.cs:

namespace NESTshop.Infrastructure
{
    public class ProductListDynamicNodeProvider : DynamicNodeProviderBase
    {
        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            using (var db = new ApplicationDbContext())
            {
                foreach (Category c in db.Category)
                {
                    DynamicNode n = new DynamicNode();
                    n.Title = c.CategoryTitle;
                    n.Key = "Kategoria_" + c.CategoryID;

                    // Optional: Add the parent key 
                    // (and put a key="Home" on the node that you want these nodes children of)
                    //n.ParentKey = "Home";

                    // Add your route values
                    // Route Option 1
                    n.RouteValues("id", c.CategoryID);

                    // Route Option 2
                    // n.RouteValues("CategoryID", c.CategoryID);

                    // Optional: Add any route values to match regardless of value
                    // n.PreservedRouteParameters.Add("myKey");

                    yield return n;
                }
            }
        }
    }
}

ProductDetailsDynamicNodeProvider.cs

namespace NESTshop.Infrastructure
{
    public class ProductDetailsDynamicNodeProvider : DynamicNodeProviderBase
    {
        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            using (var db = new ApplicationDbContext())
            {
                foreach (Product p in db.Product)
                {
                    DynamicNode n = new DynamicNode();
                    n.Title = p.ProductTitle;
                    n.Key = "Product_" + p.ProductID;

                    // IMPORTANT: Setup the relationship with the 
                    // parent node (category) by using the foreign key in 
                    // your database. ParentKey must exactly match the Key
                    // of the node this node is to be a child of.
                    // If this is a many-to-many relationship, you will need
                    // to join to the table that resolves the relationship above
                    // and use the right key here.
                    n.ParentKey = "Kategoria_" + p.CategoryID;

                    // Add your route values
                    // Route Option 1
                    n.RouteValues("id", p.ProductID);

                    // Route Option 2
                    // n.RouteValues("ProductID", p.ProductID);

                    // Optional: Add any route values to match regardless of value
                    // n.PreservedRouteParameters.Add("myKey");

                    yield return n;
                }
            }
        }
    }
}

Mvc.sitemap

如果你上面的选项设置了key为"Home",你需要在你的SiteMap"Home"中做一个节点的key,这样就有一个节点可以嵌套了它在.

<mvcSiteMapNode title="Start" controller="Home" action="Index" key="Home">

我将向您展示我的 routConfig 和站点地图文件代码:

<mvcSiteMapNode title="Start" controller="Home" action="Index">
    <mvcSiteMapNode title="Kategoria" controller="Products" action="ProductCategory" dynamicNodeProvider="NESTshop.Infrastructure.ProductListDynamicNodeProvider, NESTshop">
      <mvcSiteMapNode title="Produkt" controller="Products" action="Index"  dynamicNodeProvider="NESTshop.Infrastructure.ProductDetailsDynamicNodeProvider, NESTshop"/>
    </mvcSiteMapNode>

这里是 routConfig:

public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
              name: "Default",
              url: "{controller}/{action}/{id}",
              defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
          );
        }
    }