【问题标题】:mvcSiteMap create bredcrumb in mvc 5mvcSiteMap 在 mvc 5 中创建 bredcrumb
【发布时间】:2016-04-02 23:04:12
【问题描述】:

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

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 动作 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)时,我得到了很好的面包屑(开始 > 测试类别 1),但是当我点击 2、3、4.... 类别时,我有这个相同的面包屑(START > TEST CATEGORY 1)。

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

【问题讨论】:

    标签: c# asp.net-mvc mvcsitemapprovider


    【解决方案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

    如果您按照上面的选项将键设置为“Home”,则需要在SiteMap“Home”中设置一个节点的键,以便有一个节点可以嵌套它。

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

    【讨论】:

    • 你有我的 routConfig 和我的站点地图。当我写 n.RouteValues.Add("id", c.CategoryID);,在网站上我什么都没有。我单击类别时的 URL 示例:localhost:60804/Products/ProductCategory?CategoryID=8
    • 当我添加 parentKey("Home") 时出现此错误:+ $exception {"并非所有配置的节点都可以与父节点配对。检查您的父键以确保节点与SiteMap 中存在对应的键。
    • 你能再帮我一次吗:P 我在 _Layout.cs 中有 @Html.MvcSiteMap().SiteMapPath() 但我需要在主页上不可见,因为我只有“START”。它的属性在 mapsite.mvc 文件中执行吗?还是想什么?
    • 只需编辑/Views/Shared/DisplayTemplates/SiteMapPathHelperModel.cshtml 文件并将整个foreach 循环包装到一个if 块@if (Model.Count() &gt; 1) { // foreach here } 中。或使用visibility provider
    • 第一个解决方案是完美的:) 你是最好的。非常感谢你的朋友。
    【解决方案2】:

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

    【讨论】:

    • 您应该将此作为问题的一部分添加并删除。从技术上讲,这不是您问题的答案。
    猜你喜欢
    • 2014-09-15
    • 1970-01-01
    • 2020-07-16
    • 2013-11-10
    • 2016-05-18
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多