Stack Exchange
mvcSiteMap create bredcrumb in mvc 5
i am writing to you with one problem. I have got method:
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;
    }
}

And it should give me breadcrumb (list of categories).
I did a partial view from categories, because i have on my homepage list of categories.
Model Category:
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; }
    }
}

Partial View 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 action CategoryList:
public ActionResult CategoriesList()
        {
            List<Category> categories = categoryRepo.GetCategory().ToList();

            return PartialView(categories);
        }

and i display this in ProductCategory view:
@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>

Problem is one, when i click on category on HomePage (Test category 1) i have got good breadcrumb (START > TEST CATEGORY 1), but when i click on 2,3,4.... category i have this same breadcrumb (START > TEST CATEGORY 1).
Can u help me resolve this problem? Thank you so much!

MVC Routing
The breadcrumb is based on the current node. The current node is determined by the route values from the current request.
So you first need to ensure your routing is setup correctly so the values are read into the request as route values (which are not the same as query string values).
Route Option 1
Use "id" for all of your primary keys. This is the simplest option because the default route is the only one you need. But you need to make sure you build your URLs and action methods to use "id" rather than "CategoryID" or "ProductID".
 @Html.ActionLink(cat.CategoryTitle, "ProductCategory", "Products", new { id = cat.CategoryID }, null)

Route Option 2
Change your routing to account for use of other "id" values. This ensures your URLs are built as part of the path (/Products/ProductCategory/1234) rather than part of the query string (/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 }
      );
    }
}

Dynamic Node Provider
There are 2 things that you are responsible for in your dynamic node provider:

You have to provide all of the route values for the node to create a match with the current request
If you have nested data, you have to provide the key-parent key mapping explicitly

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
If you have set the key to "Home" as the option above, you need to make the key of a node in your SiteMap "Home" so there is a node to nest it under.
<mvcSiteMapNode title="Start" controller="Home" action="Index" key="Home">


Up u have my routConfig, and my sitemap. When i write  n.RouteValues.Add("id", c.CategoryID);, on website i have nothing. My URL when i click on Category is example: http://localhost:60804/Products/ProductCategory?CategoryID=8

and when i add parentKey("Home") i have this error: +  $exception {"Not all configured nodes could be paired with a parent node. Check your parent keys to ensure that a node with a corresponding key exists in the SiteMap.

Can u help me again :P i have @Html.MvcSiteMap().SiteMapPath() in _Layout.cs but i need to do invisible on HomePage because i have only "START". Its attribute to do it in mapsite.mvc file ? or somethink?

Just edit the /Views/Shared/DisplayTemplates/SiteMapPathHelperModel.cshtml file and wrap the whole foreach loop into an if block @if (Model.Count() > 1) { // foreach here }. Or use a visibility provider.

First solution is perfect :) u are best. Thank You so much friend.

I will show You my routConfig, and sitemap file code:
<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>

And here 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 }
          );
        }
    }


You should add this as part of your question and delete it. Technically, this is not an answer to your question.
