Click here to Skip to main content
12,956,197 members (104,465 online)
Click here to Skip to main content
Add your own
alternative version

Stats

85.7K views
1.7K downloads
63 bookmarked
Posted 1 Oct 2003

Localized Breadcrumbs in ASP.NET with UrlRewriting support

, 24 Jul 2005 CPOL
Rate this:
Please Sign up or sign in to vote.
This article describes how to create localized breadcrumb navigation with ASP.NET, based on its directory structure with UrlRewriting support.

Introduction

After I read Jon Sagara's excellent article Breadcrumbs in ASP.NET I tried to include Breadcrumbs in my web site.
But there were two problems:

  1. My Website uses UrlRewriting
  2. My Website is localized to the the User's Browser.AcceptedLanguage[0]

So I decided to write my own Breadcrumb-Control.

Background

This is my first article on CodeProject. I hope Jon Sagara isn't angry about me that i took his and mine ideas together and show what the results are, because he did the main job and gave me the inspiration for this.

What is a breadcrumb navigation

A typical web site has a directory structure. e.g.:

/
/Products
/...

A breadcrumb navigation now takes the path of the current page (e.g. http://companyname/products/default.apsx) and converts it to:

/ CompanyName / Products / Overview 

or

/ Products / Default

The Control code

if(HttpContext.Current.Application["HTTP_HOST"]==null)
{
    HttpContext.Current.Application["HTTP_HOST"] = 
           HttpContext.Current.Request.Headers["HOST"];
}
string hostName = HttpContext.Current.Application["HTTP_HOST"];
bool capitalize = false;

string requestBasePath = HttpContext.Current.Request.Path;
string requestPath = requestBasePath;
int queryStringCount = 0;
foreach ( string key in HttpContext.Current.Request.QueryString )
{
    if(queryStringCount==0)
    {
        requestPath += "?";
    }
    else
    {
        requestPath += "&";
    }
    requestPath += key + "=" + HttpContext.Current.Request.QueryString[key];
}
Assembly assmebly = Assembly.GetExecutingAssembly();
string configFile = 
   System.Web.HttpContext.Current.Request.PhysicalApplicationPath + 
   "bin\\" + assmebly.GetName().ToString().Split(',')[0] + ".config";

object breadCrumb = 
  StaticDust.Configuration.ConfigurationSettings.AppSettings(
  configFile)[System.Globalization.CultureInfo.CurrentCulture +
  "@" + requestPath];
if(breadCrumb==null)
{
    breadCrumb = StaticDust.Configuration.ConfigurationSettings.AppSettings(
        configFile)[System.Globalization.CultureInfo.CurrentCulture  + 
    "@" + requestBasePath];
    if(breadCrumb==null)
    {
        breadCrumb = 
             StaticDust.Configuration.ConfigurationSettings.AppSettings(
             configFile)[this.m_DefaultCulture + 
        "@" + requestPath];
        if(breadCrumb==null)
        {
            breadCrumb = 
                StaticDust.Configuration.ConfigurationSettings.AppSettings(
                configFile)[this.m_DefaultCulture + 
            "@" + requestBasePath];
            if(breadCrumb==null)
            {
                breadCrumb = requestBasePath;
                capitalize = true;
            }
        }
    }
}

string[] breadcrumbArr = breadCrumb.ToString().Split('/');
string outputString = "";
string urlpath = "";
for(int i=0; i<breadcrumbArr.Length; i++)
{
    if(breadcrumbArr.Length==1)
    {
        urlpath = "/" + breadcrumbArr[i];

    }
    else
    {
        if(i==0)
        {
            urlpath = "/" + m_DefaultDoc;
        }
        else if(i==(breadcrumbArr.Length-1))
        {
            urlpath += requestPath.Substring((requestPath.LastIndexOf("/")),
                 (requestPath.Length-requestPath.LastIndexOf("/")));
            if(this.m_HideFileExt==true)
            {
                breadcrumbArr[i] = breadcrumbArr[i].Substring(0, 
                   breadcrumbArr[i].LastIndexOf("."));
            }
        }
        else
        {
            urlpath += "/" + breadcrumbArr[i] + "/" + m_DefaultDoc;
        }
    }

    if(i==(breadcrumbArr.Length-1) && this.m_LinkFiles==false)
    {
        outputString += ((capitalize == true && breadcrumbArr[i].Length>=2) 
              ? (breadcrumbArr[i].Substring(0,1).ToUpper() +
              breadcrumbArr[i].Substring(1,
              (breadcrumbArr[i].Length-1)).ToLower()) : breadcrumbArr[i] ) +
              this.m_Seperator;
    }
    else
    {
        outputString += "<a href=\"" + urlpath + "\">" +
             ((capitalize == true && breadcrumbArr[i].Length>=2) ? 
             (breadcrumbArr[i].Substring(0,1).ToUpper() +
             breadcrumbArr[i].Substring(1,
             (breadcrumbArr[i].Length-1)).ToLower()) : breadcrumbArr[i] ) +
             "</a>" + this.m_Seperator;
    }
    urlpath = urlpath.Replace("/" + m_DefaultDoc,"");

}

outputString = outputString.Substring(0,
    (outputString.Length-this.m_Seperator.Length));
output.Write(outputString);
}

To get the path translated to a breadcrumb the control first checks it's configuration file (I used a custom library for that and show details of that in my next article) for an entry looking like this one:

<configuration>
  <appSettings>
    <add key="en-US@/products/default.aspx" value="CompanyName/Products" />
  </appSettings>
</configuration>

The key contains the localized culture (so you can add different values for different languages), an @ as separator and the request path. You can also define a DefaultCulture that can be used if the users culture has net been defined (default is en_US).

To support UrlRewriting via HttpContext.Current.RewritePath(...) you can also add entries looking like this:

<configuration>
  <appSettings>
    <add key=<A>en-US@/default.aspx?content=products</A> 
          value="CompanyName/Products" />
  </appSettings>
</configuration>

If the retrieved value is null the control looks for the same requested path but without the query string, so a correct bread crumb is shown when you work with query strings.

If you haven't defined anything in the configuration file the directory names and the file name will be capitalized and by default the extension is removed (/products/default.aspx gets /Products/Default).

If you are not using Visual Studio .NET you can compile the code with following command line:

csc.exe /out:StaticDust.Web.UI.Controls.BreadCrumbs.dll /target:library 
    BreadCrumbs.cs AssemblyInfo.cs /r:StaticDust.Configuration.dll

The ASP.NET code

To use the control in an .asxp page add following line to the head:

<%@ Register TagPrefix="ctrl" Namespace="StaticDust.Web.UI.Controls" 

    Assembly="StaticDust.Web.UI.Controls.BreadCrumbs" %>

And place the control tag where you want the breadcrumbs to be shown:

<ctrl:BreadCrumbs runat="server" />

History

  • 10/03/2003 v.1.0.0.0.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Daniel Fisher (lennybacon)
Software Developer
Germany Germany
Beginning of the nineties started to assemble computers and configure networks. Automation lead to batching and scripting. Arrived on the other side of the trench the HTTP protocol is a constant companion. the journey began with JavaScript, then Perl, PHP and ASP with Visual Basic 5 and JScript, ending with Java and C++. End of the nineties starting to focus .NET, streaked Python, and now JavaScript again. He develops, teaches, trains, coaches and speaks. His topics: HTML5 & Web, Data Access & Performance, Scalable & Testable Designs, Distributed Systems & Services, Security & Trust.

You may also be interested in...

Pro

Comments and Discussions

 
Generalswap url mysite.com for home in breadcrumb Pin
Sharkyinc12-Jul-12 3:24
memberSharkyinc12-Jul-12 3:24 
Generalhelp Pin
sreejith ss nair18-Sep-05 21:15
membersreejith ss nair18-Sep-05 21:15 
Good Article.

I have a small doubt regarding Globalization/Localization. Hope you can help me out.
I have a web form application where i need to provide more than 50 different localized resource supports. Apart from this, my application supports rich use of stored data (Sql Server Database) and obviously have few list of Listing controls (Repeater , Grid etc).

My requirement comes like this,

a) I need to provide full localized language support in all data which is displaying in each and every page. Regardless of, the name of controls, content of controls etc. To be concise, which ever text that i am displaying through page, need to be localized based on user selected language.

b) Each and every setup needs to contain all supported languages. So user can switch and view content of site in different language.

I stuck in,

1) I am not sure how to localize stored data in database.
2) How will I give or from where i generate localized information for all supported language.

It would be grate if you can help me out through your valid comments.


Sreejith Nair
[ My Articles ]
GeneralRe: help Pin
sreejith ss nair22-Sep-05 17:38
membersreejith ss nair22-Sep-05 17:38 
GeneralDocumentation Pin
bernardoh21-Jul-05 7:15
memberbernardoh21-Jul-05 7:15 
GeneralRe: Documentation Pin
Daniel Fisher (lennybacon)22-Jul-05 2:19
memberDaniel Fisher (lennybacon)22-Jul-05 2:19 
GeneralRe: Documentation Pin
bernardoh22-Jul-05 3:33
memberbernardoh22-Jul-05 3:33 
GeneralRe: Documentation Pin
Daniel Fisher (lennybacon)24-Jul-05 2:44
memberDaniel Fisher (lennybacon)24-Jul-05 2:44 
GeneralYour code has a flaw in it. Pin
RedMediaGab19-Aug-04 9:25
memberRedMediaGab19-Aug-04 9:25 
GeneralRe: Your code has a flaw in it. Pin
Daniel Fisher (lennybacon)22-Jul-05 2:21
memberDaniel Fisher (lennybacon)22-Jul-05 2:21 
GeneralScreenshot Pin
Heath Stewart3-Oct-03 3:07
editorHeath Stewart3-Oct-03 3:07 
GeneralRe: Screenshot Pin
Lennybacon3-Oct-03 3:54
memberLennybacon3-Oct-03 3:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 24 Jul 2005
Article Copyright 2003 by Daniel Fisher (lennybacon)
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid