Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Breadcrumbs in C# MVC Website using Bootstrap

I'm looking to add breadcrumbs to my site, but I'm not quite sure how to go about it. I have been able to get something basic working with the following code:

<ol class="breadcrumb">
    <li class="active">
        @Html.ActionLink("Home", "Index", "Home")
        @if (ViewContext.RouteData.Values["controller"] != "Home" && ViewContext.RouteData.Values["action"] != "Index")
        {
            @:> @Html.ActionLink(ViewContext.RouteData.Values["controller"].ToString(), "Index", ViewContext.RouteData.Values["controller"].ToString())
        }

        > @ViewBag.SubTitle
    </li>
</ol>

The problem I have though is that this doesn't actually track your history, it just shows you

Home > ControllerName > CurrentItem

e.g.

Home > Members > Greg Dodd

This works well when you've come from a member search page, however if you come from a different page then you lose that history. How do you create a breadcrumb trail using History in MVC?

I guess what I'm looking for is something like:

Home > Controller1 > PreviousItem > ... > CurrentItem

e.g. If you opened up a blog, then a particular blog item, then clicked the authors name, your breadcrumbs should be:

Home > Blog > SomeBlogTitle > AuthorName

If however you opened a list of authors and then chose a particular author, you would see the same view rendered using the same controller, but the breadcrumbs should show:

Home > Authors > AuthorName
like image 822
Greg Avatar asked Feb 01 '14 04:02

Greg


4 Answers

If you want a simple solution you can use this code. It is just for default routing configuration.

Home / Controller / Page

  @if (ViewContext.RouteData.Values["controller"].ToString().ToLower() != "home")
  {
       <ol class="breadcrumb">
             <li>
              @Html.ActionLink("Home", "Index", "Home")
             </li>
             <li> @Html.ActionLink(ViewContext.RouteData.Values["controller"].ToString(), "Index")
             </li>                                
             <li class="active"> @Html.ActionLink(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["action"].ToString())
             </li>                                                       
        </ol>
   }
like image 51
agenc Avatar answered Nov 20 '22 22:11

agenc


I created an OSS project to solve the problem for myself. I needed more dynamic control of the label in the breadcrumb:

https://www.nuget.org/packages/MvcBreadCrumbs

or, contribute here:

https://github.com/thelarz/MvcBreadCrumbs

like image 23
Larz Avatar answered Nov 20 '22 22:11

Larz


after install that via nuget :

PM> Install-Package MvcSiteMapProvider

then you can put this line in your Layout:

@Html.MvcSiteMap().Menu(false, true, true)

also you can customize it to fetch data from data base, first you need create a class that derives from DynamicNodeProviderBase :

   public class PostDetailsDynamicNodeProvider : DynamicNodeProviderBase
    {
        private readonly IPostService _postService;

        public PostDetailsDynamicNodeProvider()
        {
            _postService = new PostService(new MyDbContext());
        }

        public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
        {
            var returnValue = new List<DynamicNode>();

            foreach (var post in _postService.GetSiteMapData(20))
            {
                var node = new DynamicNode
                {
                    Title = post.Title,
                    Controller = "Post",
                    Action = "Index",
                    Area = "",
                    LastModifiedDate = post.ModifiedDate

                };
                node.RouteValues.Add("id", post.Id);
                node.RouteValues.Add("title", node.Title);
                returnValue.Add(node);
            }

            // Return 
            return returnValue;
        }
    }

GetSiteMapData :

public IList<SiteMapModel> GetSiteMapData(int count)
        {
            return _posts.AsNoTracking().OrderByDescending(post => post.CreatedDate).Take(count).
                          Select(post => new SiteMapModel
                              {
                                  Id = post.Id,
                                  CreatedDate = post.CreatedDate,
                                  ModifiedDate = post.ModifiedDate,
                                  Title = post.Title
                              }).ToList();
        }

then change MvcSiteMap file in your project :

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0"
            xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0 MvcSiteMapSchema.xsd"
            enableLocalization="true">
  <mvcSiteMapNode title="">
    <mvcSiteMapNode clickable="true"  title="" dynamicNodeProvider="yourCustomClassNamespace" />
  </mvcSiteMapNode>
</mvcSiteMap>
like image 6
Sirwan Afifi Avatar answered Nov 20 '22 22:11

Sirwan Afifi


<ol class="breadcrumb">


        @if (ViewContext.RouteData.Values["controller"].ToString() != "Home")
        {
            @Html.ActionLink("Home", "Index", "Home")
            <li class="active">
                / @ViewBag.Title
            </li>
        }
        else
        {
            <li class="active">
                Home
            </li>
        }

    </ol>

Work for you with bootstrap

like image 1
Thanhnx Avatar answered Nov 21 '22 00:11

Thanhnx