A Simple and Dynamic BreadCrumb Web User Control for ASP.NET

Introduction

The term Breadcrumb comes from the story of Hansel and Gretel. While going through the forest, they left breadcrumbs on the way to remember the route. Many of today's Web sites today (for example, Yahoo) use this concept. A user surfing the site is inside a forest. Breadcrumbs in Web sites show the path the user has taken to reach the current page. They can also tell the hierarchy of the page inside the site. Some sites depend on the directory structure of the site to form the breadcrumb. It splits the virtual path of the directory and shows each directory as a link in the breadcrumb. Here, I will design a breadcrumb that forms the links dynamically by remembering the path the user has taken. It can also remember the querystring passed to the page on the last visit.

Assumptions

I make some assumptions about the breadcrumb. These assumptions act as the requirements for my breadcrumb. If anybody has a different set of requirements, we can think of enhancing the system.

  1. Each page has a level in the site. This level determines the hierarchy of the page irrespective of the directory structure. The home page is Level 1.
  2. The user always goes from higher-level pages to lower-level pages. For example, the navigation will be 1-2-3 or 1-2-4, but not 1-4-2.
  3. If the user comes back to the higher level from a lower level, we can ignore the lower levels. We are not forming a cycle in the breadcrumb. In other words, there won't be a breadcrumb in the form 1-2-3-4-2. If such navigation happens, the Breadcrumb will be 1-2.
  4. The breadcrumb will always start with Level 1. If the user directly comes to Level 4 (by using a short cut), the breadcrumb should show 1-4.
  5. The breadcrumb should remember the querystring variables of the page.
  6. Each page declares its name to appear in the breadcrumb.

Design and Implementation

Selection of objects

In the breadcrumb, we need to track the state of the previous pages. In ASP.NET, we have a Session object to keep track of the state. The session object should store the state information of multiple pages. So, it would be better to choose any of the collection classes. According to Assumption 2, the breadcrumb should keep an order based on the level. This made me choose SortedList as my collection. We need to store the name, querystring, and url of the page to create the breadcrumb. A structure by the name of PageCrumb can do it.

Implementation strategy

Our BreadCrumb control accepts the Level and Name of the Page from the container page and creates a PageCrumb object. It can get the url and querystring from the request object. The control modifies the SortedList by comparing the levels of the existing PageCrumb objects in the list. The modification means the removal of all lower-level PageCrumb objects from the list. Once the modification is complete, the control can create the breadcrumb by iterating through the SortedList. The BreadCrumb control contains a label whose Text property can be set as our dynamically created breadcrumb.

The Code

The following structure represents the class that can hold the level, url, and linkName of the page. I also keep the level inside the PageCrumb to make it more meaningful even though it is not required for the implementation.

Public Structure PageCrumb

   Private _level As Short
   Private _url As String
   Private _linkName As String

   //We are setting all the properties at the time of construction

   Public Sub New(ByVal level As Short, ByVal url As String,
          ByVal linkName As String)

      _level = level
      _url = url
      _linkName = linkName
   End Sub

   //We are making all the properties as read-only.
   //We are not expecting it to change once it is set.
   Public ReadOnly Property Level() As Short
   Get
      Return _level
   End Get
   End Property

   Public ReadOnly Property Url() As String
   Get
      Return _url
   End Get
   End Property

   Public ReadOnly Property LinkName() As String
   Get
      Return _linkName
   End Get
   End Property
End Structure

The Vb file of the BreadCrumbControl will contain the following code

Declare the following variables:

'Variable holding the Link name of the page
Private _tailName As String
'Variable holding the level of the page
Private _level As Short
'The pagecrumb object of the current page
Private _pageCrumb As New PageCrumb
'We will use a sorted list as we can use the level as key
Private _crumbList As SortedList

Define the following properties:

'Each page has a level. The page should declare its level
Public Property Level() As Short
' TO DO: We can check for some constraints here
   Get
      Return _level
   End Get
   Set(ByVal Value As Short)
      _level = Value
   End Set
End Property

'Each page needs a meaningful name of it. Let them declare it
Public Property TailName() As String
   ' TO DO: We can check for some constraints here
   Get
      Return _tailName
   End Get
   Set(ByVal Value As String)
      _tailName = Value
   End Set
End Property

Modify the Page_Load event by adding the following code. We are creating the PageCrumb object by using the Request.RawUrl. This RawUrl property also contains querystring information. This information helps us to open the page with the querystring once the user comes back to the page.

Private Sub Page_Load(ByVal sender As System.Object, _
                      ByVal e As System.EventArgs) _
                      Handles MyBase.Load
   'We are not disabling viewstate
   If Not (Page.IsPostBack) Then

   'Minimum level is 1
   If (_level <= 0) Then
      _level = 1
   End If

   'If no friendly name gives Untitled as default
   If (_tailName = "") Then
      _tailName = "Untitled"
   End If

   'Create a Crumb object based on the properties of this page
   _pageCrumb = New PageCrumb(_level, Request.RawUrl, _tailName)

 

'Check that our Crumb is there in the session...if not, create 'and add it...else get it If Session.Item("HASH_OF_CRUMPS") Is Nothing Then crumbList = New SortedList Session.Add("HASH_OF_CRUMPS", _crumbList) Else _crumbList = Session.Item("HASH_OF_CRUMPS") End If 'Now modify the List of the breadcrumb ModifyList() 'Put the breadcrumb from the session of sortlist PutBreadCrumbs() End If End Sub

The following function checks the level of the page. If the level is 1, it removes everything from the list and adds the home link. I assume that the Home page is always the first-level page. If there is nothing in the list, we add the Home page to the list. Please remember our Assumption 4 here. Also note the GlobalMembers.HOME_LINK_PATH. It is a string that represents the Url of the home page.

Private Sub ModifyList()
'Remove all Entries from the list that are higher or equal in level
'because at a level there can be max of 1 entry in the list
RemoveLowerLevelCrumbs()
'If level is 1 set the Crumb as home
If _pageCrumb.Level = 1 Then
   _crumbList.Clear()
   _crumbList.Add(CType(1, Short), New PageCrumb(1, _
                  GlobalMembers.HOME_LINK_PATH, "Home"))
Else
   'If nothing in the list adds the home link first
   If _crumbList.Count = 0 Then
      _crumbList.Add(CType(1, Short), New PageCrumb(1, _
                     GlobalMembers.HOME_LINK_PATH, "Home"))
   End If
   'Now add the present list; also, no other check is required here
   'as we have cleaned up the List at the start of the function
      _crumbList.Add(_level, _pageCrumb)
   End If
End Sub

As per our Assumption 3, the breadcrumb should not create a cycle. The following function removes all lower-level pages from the list.

'Function will remove all the entries from the list that are higher
'than or equal to the present level
Private Sub RemoveLowerLevelCrumbs()

Dim level As Short
Dim removalList As New ArrayList(_crumbList.Count)
For Each level In _crumbList.Keys
   If (level >= _level) Then
      removalList.Add(level)
   End If
   Next
   'Now remove all keys in the list
   For Each level In removalList
      _crumbList.Remove()
   Next
End Sub

Now, we can create the breadcrumb by using the list. I am using > as the separator. Also, the last name in the breadcrumb is not a link because it denotes the current page.

Private Sub PutBreadCrumbs()
Dim linkString As New StringBuilder

   Dim pageCrumb As New PageCrumb
   Dim index As Integer

   For index = 0 To _crumbList.Count - 2
      pageCrumb = _crumbList.GetByIndex)
      linkString.Append(String.Format("<a href = {0} >{1} </a>", _
                        pageCrumb.Url, pageCrumb.LinkName))
      linkString.Append(" > ")
   Next index
   'Add the tail also
   pageCrumb = _crumbList.GetByIndex(index)
      linkString.Append(pageCrumb.LinkName)
      lblTrail.Text = linkString.ToString()

   End Sub

End Class

How to Use This Control

Add this user control to any page on which you need a breadcrumb. Then, set the Level and Name properties of the control. I have attached some sample files showing the usage of the control. They also contain the complete source code of the implementation.

Limitations

The above-described BreadCrumb cannot remember the actions happening on the page during postback. We can expose an additional property of the Object type in the PageCrumb object to do this. The calling page can use this object to store any additional information it needs. But, this requires some coding in the container page, so I avoided it. Somebody else can take a better shot on this. Because we are storing the information in the session, we should be a little careful about the number of levels our Web site will have.



About the Author

Gibi Joseph Poovathumkudy

Gibi has more than 3 years of experience in MS Technologies. He has worked in various MS technologies like VC++, COM, COM+, ASP.Net, C#, VB.Net, WebServices, Exchange Server, Host Integration Server, SQL Server, Biztalk Server MSMQ, CDO etc. He is in Love with Microsoft.

Downloads

Comments

  • Need a help

    Posted by splendorsaran on 08/26/2010 11:07pm

    Hi How we can improve by directly browsing the higher level , Lets say if we browse directly to 1.4 then it should display all the level 1.1.,1.2 and 1.3 in the page. Thanks this is bit urgent can you please help

    Reply
  • need a little help....

    Posted by jsegreti on 12/06/2007 04:09pm

    When I run to this part of code listed below, the _crumbList has nothing in the list. (I did step through and witness the info being loaded into the list.) But by the time it hits the code listed below there's nothing there. Can you help?

    Reply
  • Hi your code works fine

    Posted by kullanici34 on 09/28/2007 04:14am

    But only one thing how can i change this: I want the the current page to be displayed not as hyperlink, i want it just plain text, how can you modify that? Thanx

    Reply
  • How about a page url created by query and has & etc

    Posted by kullanici34 on 09/27/2007 08:45am

    And one more thing: I have one page called after "results" page called "details.asp" and its url created by results.asp page's query and that one is for example: http://www.erden.com/a_details.asp?T_PropertyREF=8561&mVarTable=[details] thanx , Oscar

    Reply
  • BREADCRUMB style navigation displays file names but i dont want that

    Posted by kullanici34 on 09/27/2007 08:35am

    Hi, Mr Joseph, this is great script (breadcrumbs) and I inserted this to every page as "inc_crumbs.asp" in my site. It works fine but one thing I cant configure is that: It displays the file names as for example: search.asp or results.asp etc... But i want it to display as SEARCH or RESULTS etc... How to implement this? Can it display only page title name or something else how can you change it? Can you help please, thanx. Oscar

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Protecting business operations means shifting the priorities around availability from disaster recovery to business continuity. Enterprises are shifting their focus from recovery from a disaster to preventing the disaster in the first place. With this change in mindset, disaster recovery is no longer the first line of defense; the organizations with a smarter business continuity practice are less impacted when disasters strike. This SmartSelect will provide insight to help guide your enterprise toward better …

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds