Click here to Skip to main content
15,885,757 members
Articles / Web Development / ASP.NET

Localized Breadcrumbs in ASP.NET with UrlRewriting support

Rate me:
Please Sign up or sign in to vote.
3.64/5 (10 votes)
24 Jul 2005CPOL2 min read 95.2K   1.7K   62  
This article describes how to create localized breadcrumb navigation with ASP.NET, based on its directory structure with UrlRewriting support.
using System;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Reflection;
using StaticDust.Configuration;

namespace StaticDust.Web.UI.Controls
{
	/// <summary>
	/// Localized Breadcrumbs for ASP.NET with UrlRedirect support.
	/// </summary>
	[DefaultProperty("Seperator"), ToolboxData("<{0}:BreadCrumbs runat=server></{0}:BreadCrumbs>")]
	public class BreadCrumbs : System.Web.UI.WebControls.WebControl
	{
		#region Seperator
		/// <summary>This field holds the value of the Seperator.</summary>
		private string m_Seperator = "&nbsp;/&nbsp;";

		/// <summary>This property gets/sets the value of the Seperator.</summary>
		/// <value>A <see cref="string">string</see> with the value of the Seperator.</value>
		/// <remarks>This property gets/sets the value of the Seperator.</remarks>
		[Bindable(true), Category("Appearance"), DefaultValue("&nbsp;/&nbsp;")]
		public string Seperator
		{
			get
			{
				return (this.m_Seperator);
			}
			set
			{
				this.m_Seperator = value;
			}
		}
		#endregion

		#region DefaultCulture
		/// <summary>This field holds the value of the DefaultCulture.</summary>
		private string m_DefaultCulture = "en-US";

		/// <summary>This property gets/sets the value of the DefaultCulture.</summary>
		/// <value>A <see cref="string">string</see> with the value of the DefaultCulture.</value>
		/// <remarks>This property gets/sets the value of the DefaultCulture.</remarks>
		[Bindable(true), Category("Appearance"), DefaultValue("en-US")]
		public string DefaultCulture
		{
			get
			{
				return (this.m_DefaultCulture);
			}
			set
			{
				this.m_DefaultCulture = value;
			}
		}
		#endregion

		#region DefaultDoc
		/// <summary>This field holds the value of the DefaultDoc.</summary>
		private string m_DefaultDoc = "default.aspx";

		/// <summary>This property gets/sets the value of the DefaultDoc.</summary>
		/// <value>A <see cref="string">string</see> with the value of the DefaultDoc.</value>
		/// <remarks>This property gets/sets the value of the DefaultDoc.</remarks>
		//[Bindable(true), Category("Appearance"), DefaultValue("")]
		//[BusinessObjects.DataColumn("DefaultDoc")]
		public string DefaultDoc
		{
			get
			{
				return (this.m_DefaultDoc);
			}
			set
			{
				this.m_DefaultDoc = value;
			}
		}
		#endregion

		#region HideFileExt
		/// <summary>This field holds the value of the HideFileExt.</summary>
		private bool m_HideFileExt = true;

		/// <summary>This property gets/sets the value of the HideFileExt.</summary>
		/// <value>A <see cref="bool">string</see> with the value of the HideFileExt.</value>
		/// <remarks>This property gets/sets the value of the HideFileExt.</remarks>
		//[Bindable(true), Category("Appearance"), DefaultValue("")]
		//[BusinessObjects.DataColumn("HideFileExt")]
		public bool HideFileExt
		{
			get
			{
				return (this.m_HideFileExt);
			}
			set
			{
				this.m_HideFileExt = value;
			}
		}
		#endregion

		#region LinkFiles
		/// <summary>This field holds the value of the LinkFiles.</summary>
		private bool m_LinkFiles = false;

		/// <summary>This property gets/sets the value of the LinkFiles.</summary>
		/// <value>A <see cref="bool">string</see> with the value of the LinkFiles.</value>
		/// <remarks>This property gets/sets the value of the LinkFiles.</remarks>
		//[Bindable(true), Category("Appearance"), DefaultValue("")]
		//[BusinessObjects.DataColumn("LinkFiles")]
		public bool LinkFiles
		{
			get
			{
				return (this.m_LinkFiles);
			}
			set
			{
				this.m_LinkFiles = value;
			}
		}
		#endregion


		#region protected override void Render(HtmlTextWriter output)
		/// <summary>
		/// Sends server control content to a provided <see cref="System.Web.UI.HtmlTextWriter">HtmlTextWriter</see> object, which writes the content to be rendered on the client.
		/// </summary>
		/// <param name="output">The <see cref="System.Web.UI.HtmlTextWriter">HtmlTextWriter</see> object that receives the server control content. </param>
		/// <remarks>When developing custom server controls, you can override this method to generate content for an ASP.NET page.</remarks>
		protected override void Render(HtmlTextWriter output)
		{
			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];
				queryStringCount++;
			}
			Assembly assmebly = Assembly.GetExecutingAssembly();
			string configFile = System.Web.HttpContext.Current.Request.PhysicalApplicationPath + "bin\\" +
								assmebly.GetName().ToString().Split(',')[0] + ".config";

			object breadCrumb = CustomConfigurationSettings.AppSettings(configFile)[System.Globalization.CultureInfo.CurrentCulture + "@" + requestPath];
			if(breadCrumb==null)
			{
				breadCrumb = CustomConfigurationSettings.AppSettings(configFile)[System.Globalization.CultureInfo.CurrentCulture + "@" + requestBasePath];
				if(breadCrumb==null)
				{
					breadCrumb = CustomConfigurationSettings.AppSettings(configFile)[this.m_DefaultCulture + "@" + requestPath];
					if(breadCrumb==null)
					{
						breadCrumb = CustomConfigurationSettings.AppSettings(configFile)[this.m_DefaultCulture + "@" + requestBasePath];
						if(breadCrumb==null)
						{
							breadCrumb = requestPath;
							capitalize = true;
						}
					}
				}
			}
			
			string[] breadcrumbArr = (((breadCrumb.ToString().Substring(0,1)=="/") ? HttpContext.Current.Request.Headers["HOST"] : "" ) + breadCrumb.ToString()).Split('/');
			string outputString = "";
			string urlpath = "";
			for(int i=0; i<breadcrumbArr.Length; i++)
			{
				//output.Write("urlpath: " + breadcrumbArr[i].Length + " : \"" + breadcrumbArr[i] + "\"<br/>");

				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(".")==-1) ? breadcrumbArr[i].Length : breadcrumbArr[i].LastIndexOf(".")));
						}
					}
					else	
					{
						urlpath += "/" + breadcrumbArr[i] + "/" + m_DefaultDoc;
					}
					//output.Write("urlpath: " + urlpath+" : " + breadcrumbArr[i] + "<br/>");
				}
				
				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);
		}
		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
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.

Comments and Discussions