mvcSiteMap在mvc 5中创建bredcrumb

时间:2016-04-02 09:43:56

标签: c# asp.net-mvc mvcsitemapprovider

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

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;
    }
}

它应该给我一个breadcrumb(类别列表)。

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

模特类别:

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; }
    }
}

部分查看ProductCategory

@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动作CategoryList:

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)时,我有好的面包屑(START&gt; TEST CATEGORY 1),但是当我点击2,3,4 ....类别我有同样的面包屑(START&gt; TEST CATEGORY 1)。

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

2 个答案:

答案 0 :(得分:1)

MVC路由

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

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

路线选项1

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

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

路线选项2

将路由更改为帐户以使用其他“id”值。这可确保您的网址构建为路径(/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. 如果您有嵌套数据,则必须明确提供键 - 父键映射
  3. 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

    如果您将密钥设置为“Home”作为上述选项,则需要在SiteMap“Home”中创建节点的密钥,以便有一个节点将其嵌套在其中。

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

答案 1 :(得分:0)

我将向您显示我的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 }
          );
        }
    }