Breadcrumbs within Razor page .Net Core

chriscooper01

Chris Cooper

Posted on April 18, 2020

Breadcrumbs within Razor page .Net Core

I'm still quite new to Razor pages (not mvc) and wanted a Breadcrumb navigation bar on my pages, which was created dynamically. I looked around but in the end I created my own and this is how I did it. There is a full example of my solution on a .net core razor page solution on git.

The Breadcrumb creation

This is created within a class that will be inherited on the pagemodel class. This is broken down into many smaller part to make it easier.

Validating the Request

Firs you need to make sure the Request has a path and a query string, before you start looking at making the bread crumbs

    public void Validate()
    {
        currentQuery = String.Empty;
        currentPath = String.Empty;
        referers = this.Request.Headers["Referer"].ToList(); ;
        if (this.Request.Path.HasValue)
            currentPath = this.Request.Path.Value.Replace("/", String.Empty);
        if (this.Request.QueryString.HasValue)
            currentQuery = this.Request.QueryString.Value;

    }

Get current bread crumbs

This logic uses a session with a JSON object, containing all needed data for my breadcrumbs

    private  void getCurrentBreadCrumbs()
    {
        var sessionString = HttpContext.Session.GetString("BreadCrumbs");
        breadCrumbs = new List<DataClassesLibrary.BreadCrumbDataClass>();
        if (String.IsNullOrWhiteSpace(sessionString) || sessionString.Equals("[]"))
            return;

        breadCrumbs = (List<DataClassesLibrary.BreadCrumbDataClass>)HelperLibrary.JsonStringHelper.GetObject(sessionString, breadCrumbs.GetType());

    }

Setting new bread crumb

Now I have my current and a valid request object, I can see if I need to set a new bread crumb for the current page.

    private  void setBreadCrumbs()
    {
        if (referers.Count > 0)
        {
            var urlValue = referers[0].ToString();
            var urlElements = urlValue.Split("/").ToList();
            var hostLocation = urlElements.IndexOf(this.Request.Host.Value);
            if (urlElements.Count() > hostLocation)
            {
                var razorPageURL = urlElements[hostLocation + 1];
                var razorPage = razorPageURL.Split("?");
                if (razorPage.Count() > 0)
                {
                    var data = new DataClassesLibrary.BreadCrumbDataClass();
                    data.Key = razorPage[0].ToString();
                    //Make sure I'm not adding the page back in I have removed
                    if (crumbRemoved.FirstOrDefault(x => x.Equals(data.Key)) != null)
                        return;

                    if (setCurrentAsDisabled(data.Key))                        
                        return;//Do not set if already exists


                    if (razorPage.Count().Equals(2))
                    {                            
                        data.Parameters = setParameters(razorPage[1]);
                    }
                    breadCrumbs.Add(data);
                }

            }                
        }
    }

Set the session

Because I use a session with a JSON object, to hold my current breadcrumbs, I will set the session with the new data.

    private void setSession()
    {
        HttpContext.Session.Set("BreadCrumbs", System.Text.Encoding.UTF8.GetBytes(HelperLibrary.JsonStringHelper.GetString(breadCrumbs)));
    }

Creating the HTML breadscrumb

This goes through my Bread crumbs List object and creates the required simple HTML.

Navigation bar

This is the main method that creates the navigation bar

    public string SetNavString(List<DataClassesLibrary.BreadCrumbDataClass> crumbs)
    {
        if (crumbs == null || crumbs.Count.Equals(0))
            return String.Empty;

        var nav = new StringBuilder();
        nav.AppendLine("<nav aria-label=\"breadcrumb\">");
        nav.AppendLine("<ol class=\"breadcrumb\">");

        foreach (var crumb in crumbs)
            nav.AppendLine(setLinkItem(crumb));

        nav.AppendLine("</ol>");
        nav.AppendLine("</nav>");
        return nav.ToString();
    }

Creating the linked item

This is how I have created the linked item, within the Navigation bar

    private static string setLinkItem(DataClassesLibrary.BreadCrumbDataClass crumb)
    {
        var item = new StringBuilder();
        if (!crumb.Current)
        {
           item.AppendLine("<li class=\"breadcrumb-item \">");
           item.AppendLine(String.Format("<a href=\"{0}{1}\" >{0}</a>", crumb.Key, setLinkItemParemeters(crumb)));
        }
        else
        {
            item.AppendLine("<li class=\"breadcrumb-item active\" aria-current=\"page\">");
            item.AppendLine(crumb.Key);
        }

        item.AppendLine("</li>");
        return item.ToString();
    }

Setting parameters

Setting the parameters for a linked item

    private static string setLinkItemParemeters(DataClassesLibrary.BreadCrumbDataClass crumb)
    {
        if (crumb.Parameters == null || crumb.Parameters.Count.Equals(0))
            return String.Empty;

        var parameter = new List<string>();
        foreach (var p in crumb.Parameters)
        {
            parameter.Add(String.Format("{0}={1}", p.Key, p.Value));
        }

        return "?" + String.Join("&", parameter.ToArray());
    }

Invoke the build

Once you have inherited the build class you call the build or reset method on the OnGet method.

public class FlagListModel : Pages.Extended.BreadCrumbsExtended
{

    public void OnGet()
    {
        SetBreadCrumbs();          

    }
}

Bread crumbs extended class

The SetBreadCrumbs method sits within the extended class and looks like below

    public  void SetBreadCrumbs()
    {   
        currentQuery = String.Empty;
        currentPath = String.Empty;
        referers = this.Request.Headers["Referer"].ToList(); ;
        if (this.Request.Path.HasValue)
            currentPath = this.Request.Path.Value.Replace("/", String.Empty);
        if (this.Request.QueryString.HasValue)
            currentQuery = this.Request.QueryString.Value;

        getCurrentBreadCrumbs();

        checkGoingBack();
        setBreadCrumbs();

        setCurrent();
        setSession();

        BreadCrumb = BreadCrumbsNavigationExtended.SetNavString(breadCrumbs);
        //Dispos
        currentQuery = String.Empty;
        currentPath = String.Empty;
        referers = null;
        breadCrumbs = null;
    }

Show the navigation bar
Now you have inherited and invoked the build, you want to show the navigation bar. This is done simply by placing the single line.

@Html.Raw(Model.BreadCrumb)

Now you have inherited and invoked the build, you want to show the navigation bar. This is done simply by placing the single line.

Full solution
The full solution can be found within my public GitHub repo.
The SetBreadCrumbs logic is done on the Privacy page. The WipeBreadCrumbs logic is done on the index (home) page

GitHub

💖 💪 🙅 🚩
chriscooper01
Chris Cooper

Posted on April 18, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related