Click here to Skip to main content
15,881,898 members
Articles / Web Development / ASP.NET
Article

Navigation using dynamic SiteMapPath file

Rate me:
Please Sign up or sign in to vote.
2.83/5 (21 votes)
16 Jan 20062 min read 135.7K   56   17
This article demonstrates the ASP.NET 2.0 feature to extend menu generation using SiteMapPath.

Introduction

This article demonstrates the ASP.NET 2.0 feature to extend menu generation using SiteMapPath. Here, I will be showing how to generate the Web.Sitemap file using the XmlTextWriter at runtime, retrieving the data from SQL Server.

The code

First, I would like to show you the database structure, I have two tables in the database:

  1. Master
  2. Child

Following are the screenshots of the tables:

Master

Image 1

Child

Image 2

To fetch data from the database, I have created two connections:

C#
string _sqlconnString = 
       "server=yoursever;User ID=sa;Password=sa;database=test";
 
SqlConnection source = new SqlConnection(_sqlconnString);
// Create destination connection
SqlConnection destination = new SqlConnection(_sqlconnString);
//Open connections
source.Open();
destination.Open();
// Select data from Products table
SqlCommand cmd = new SqlCommand("SELECT * FROM Master", source);
SqlCommand cmd1 = new SqlCommand("SELECT * FROM Child", destination);
// Execute reader
SqlDataReader reader1 = cmd.ExecuteReader();

Once I get the data from the database, I look into the format of the Web.Sitemap file which has to follow certain formats. The root node must be <siteMap> and that should be followed by <siteMapNode>. The first SiteMapNode refers to the root level of the menu so you can't afford to have multiple <SiteMapNode> under the <SiteMap> tag. So, a well formed XML for a site map would look like the following:

XML
<?xml version="1.0" encoding="utf-8"?>
<siteMap>
 <siteMapNode title="hello" description="hello" url="hello">
 <siteMapNode title="Himanshu" 
      description="Himanshu ALive" url="http://www.yah1oo.com">
 <siteMapNode title="Himanshu1" 
      description="Himanshu1 Alive" url="http://www.yah3oo.com" />
 <siteMapNode title="Himanshu2" 
      description="Himanshu2 Alive" url="http://www.ya4hoo.com" />
 </siteMapNode><siteMapNode title="Dhami" 
      description="Dhami Alive" url="http://www.ya2hoo.com">
 <siteMapNode title="Dhami1" 
      description="Dhami1 Alive" url="http://www.ya5hoo.com" />
 <siteMapNode title="Dhami2" 
      description="Dhami2 Alive" url="http://www.ya6hoo.com" />
 </siteMapNode><siteMapNode title="Dell" 
      description="Dell Alive" url="http://www.dell.com" />
 </siteMapNode>
</siteMap>

Now comes the interesting part, we need to generate the above XML file based on the data retrieved from the SQL Server. As stated above, we have two connections open to the database for retrieving data from the Master and the Child tables.

The first step is to create the XML file, which we will do using the XMLTextWriter as shown below:

C#
//Create XML
Encoding enc = Encoding.UTF8;
XmlTextWriter objXMLTW = new XmlTextWriter(sFileName, enc);

where sFileName is the path of the root directory of your application where you want to generate the Web.SiteMap file. For me, it is something like this:

sFileName=D:\VS2005PROJECTS\TESTASPNET\Web.SiteMap

Now we have created the XML file, so we need to create the required structure based on the fetched data.

<siteMapNode> requires three attributes:

  • Title: Displayed in the menu.
  • Description: This can be anything.
  • URL: Link to some other website when clicked.

Now, I am pasting the code to generate the <siteMap> and the first <siteMapNode>. You can follow them with the comments specified:

C#
try
{
    objXMLTW.WriteStartDocument();//xml document open
    //'Top level (Parent element)
    //root node open
    objXMLTW.WriteStartElement("siteMap");
    //first Node of the Menu open
    objXMLTW.WriteStartElement("siteMapNode");
    objXMLTW.WriteAttributeString("title", 
        "Home");//Title attribute set
    objXMLTW.WriteAttributeString("description", 
        "This is home");//Description attribute set
    objXMLTW.WriteAttributeString("url", 
        "http://www.home.com");//URL attribute set
    //Loop and create nodes

The above code will generate the root node and the first node for the menu, as shown below:

XML
<?xml version="1.0" encoding="utf-8"?>
 <siteMap>
 <siteMapNode title="hello" description="hello" url="hello">

Once we are done with this, we will be looping through the master DataReader and creating the master node elements:

C#
while (reader1.Read())
{
    int MasterID = reader1.GetInt32(0);
    objXMLTW.WriteStartElement("siteMapNode");
    objXMLTW.WriteAttributeString("title",
                    reader1.GetString(1));
    objXMLTW.WriteAttributeString("description",
                          reader1.GetString(2));
    objXMLTW.WriteAttributeString("url",
                  reader1.GetString(3));

Inside the same loop, we will loop through the child DataReader, and if the masterId for the master table matches the master ID for the child table then, we will generate the <SiteMapNode> for the child elements also. This can go down deeper on the basis of the master and the child table structure.

To retrieve the desired data, we will open the child DataReader as shown below:

C#
SqlDataReader reader2 = cmd1.ExecuteReader();
while (reader2.Read())
{
    int ChildMasterID = reader2.GetInt32(1);
    if (MasterID == ChildMasterID)
    {
        //Open Child Element
        objXMLTW.WriteStartElement("siteMapNode");
        objXMLTW.WriteAttributeString("title",
                        reader2.GetString(2));
        objXMLTW.WriteAttributeString("description",
                              reader2.GetString(3));
        objXMLTW.WriteAttributeString("url",
                      reader2.GetString(4));
        objXMLTW.WriteEndElement();//Close Child Element
    }
}
reader2.Close();//Close the child datareader
objXMLTW.WriteEndElement();//Close the siteMapNode

After this, we just need to close the first siteMapNode and close the creation of the XML document:

C#
    }
    objXMLTW.WriteEndElement();//Close the first siteMapNode
    objXMLTW.WriteEndDocument();//xml document closed
}
finally
{
    objXMLTW.Flush();
    objXMLTW.Close();
}
destination.Close();
source.Close();

The above code generates the required Web.SiteMap file in the root directory of the application, and you need to write a function using the code shown above. Just call the function in the Page_Load and it will update the Web.SiteMap file every time you run it. The sample menu looks like this:

Image 3

This is how the entire code looks like:

C#
private void GenerateXMLFile(string sFileName)
{
    string _sqlconnString = 
           "server=nouswk124;User ID=sa;Password=sa;database=test";
    string _destsqlconnString = 
           "server=nouswk124;User ID=sa;Password=sa;database=test";
    SqlConnection source = new SqlConnection(_sqlconnString);
    // Create destination connection
    SqlConnection destination = new SqlConnection(_destsqlconnString);
    //Open connections
    source.Open();
    destination.Open();
    // Select data from Products table
    SqlCommand cmd = new 
               SqlCommand("SELECT * FROM Master", source);
    SqlCommand cmd1 = new 
               SqlCommand("SELECT * FROM Child", destination);
    // Execute reader
    SqlDataReader reader1 = cmd.ExecuteReader();
  
    //Create XML
    Encoding enc = Encoding.UTF8;
    XmlTextWriter objXMLTW = new XmlTextWriter(sFileName, enc);
    try
    {          
        objXMLTW.WriteStartDocument();//xml document open
        //'Top level (Parent element)
        //root node open
        objXMLTW.WriteStartElement("siteMap");
        //first Node of the Menu open
        objXMLTW.WriteStartElement("siteMapNode");
        //Title attribute set
        objXMLTW.WriteAttributeString("title", "Home");
        objXMLTW.WriteAttributeString("description", 
                 "This is home");//Description attribute set
        objXMLTW.WriteAttributeString("url", 
                 "http://www.home.com");//URL attribute set
        //Loop and create nodes
        while (reader1.Read())
        {
            int MasterID = reader1.GetInt32(0);
            objXMLTW.WriteStartElement("siteMapNode");
            objXMLTW.WriteAttributeString("title", 
                            reader1.GetString(1));
            objXMLTW.WriteAttributeString("description", 
                                  reader1.GetString(2));
            objXMLTW.WriteAttributeString("url", 
                          reader1.GetString(3));

            //objXMLTW.WriteString("No Nonsense" + 
                                    i.ToString());
            SqlDataReader reader2 = cmd1.ExecuteReader();
            while (reader2.Read())
            {
                int ChildMasterID = reader2.GetInt32(1);
                if (MasterID == ChildMasterID)
                {
                    //Open Child Element
                    objXMLTW.WriteStartElement("siteMapNode");
                    objXMLTW.WriteAttributeString("title", 
                                    reader2.GetString(2));
                    objXMLTW.WriteAttributeString("description", 
                                          reader2.GetString(3));
                    objXMLTW.WriteAttributeString("url", 
                                  reader2.GetString(4));
                    objXMLTW.WriteEndElement();
                    //Close Child Element
                }
            }
            reader2.Close();//Close the child datareader
            objXMLTW.WriteEndElement();//Close the siteMapNode
        }
        objXMLTW.WriteEndElement();//Close the first siteMapNode
        objXMLTW.WriteEndDocument();//xml document closed
    }
    finally
    {
        objXMLTW.Flush();
        objXMLTW.Close();
    }

    destination.Close();
    source.Close();
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhere to create this code? Pin
Veeravadhani MN21-Nov-13 8:21
Veeravadhani MN21-Nov-13 8:21 
GeneralMy vote of 2 Pin
Smart_Boy27-Sep-12 22:16
Smart_Boy27-Sep-12 22:16 
GeneralMy vote of 4 Pin
Rajakulai24-Jun-12 21:10
Rajakulai24-Jun-12 21:10 
Generalhelp Pin
fronksk813-Apr-10 10:32
fronksk813-Apr-10 10:32 
GeneralMy vote of 1 Pin
Syed J Hashmi26-Nov-09 0:39
Syed J Hashmi26-Nov-09 0:39 
GeneralSuggestion Pin
Vikas Misra(TCS)3-Aug-09 1:08
Vikas Misra(TCS)3-Aug-09 1:08 
Dear Himanshu,

Nice trick, just write your site map in your own way but dont you think its not a good idea to put it on page load, You can use Application_Start event in global config file just to minimize the database calls or you can use session_start event too depending upon the freequency of datachange.If the database values changes are very fast then you can use this on pageload but can utilize asp.net caching mechanism
to regenerate your site map.
Smile | :)
Questionhow to work with sitemappath control Pin
jayakrishna084-Aug-07 1:09
jayakrishna084-Aug-07 1:09 
JokeThis is a best game ! Pin
BaoJFK1-Feb-07 15:15
BaoJFK1-Feb-07 15:15 
GeneralNot an impressive idea Pin
Pankudonald18-Oct-06 9:26
Pankudonald18-Oct-06 9:26 
QuestionRe: Not an impressive idea Pin
bonjodude15-Jun-07 8:33
bonjodude15-Jun-07 8:33 
GeneralNot Ideal Solution Pin
Santosh K Sahoo11-Sep-06 1:37
Santosh K Sahoo11-Sep-06 1:37 
GeneralGreat article Pin
gr8design11-May-06 11:27
gr8design11-May-06 11:27 
AnswerRe: Great article Pin
Himanshu D11-May-06 19:51
Himanshu D11-May-06 19:51 
GeneralHello Himanshu!! Pin
hoang loc10-Apr-06 23:47
hoang loc10-Apr-06 23:47 
QuestionWhy? Pin
aprenot16-Jan-06 6:57
aprenot16-Jan-06 6:57 
AnswerRe: Why? Pin
Himanshu D16-Jan-06 18:14
Himanshu D16-Jan-06 18:14 
GeneralKnown Issue of opening datareader multiple time Pin
Himanshu D16-Jan-06 6:27
Himanshu D16-Jan-06 6:27 

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.