Create new account I forgot my password    

Creating an ASP.NET SiteMap dynamically using LINQ and bind to a TreeView
Rating: 15 user(s) have rated this article Average rating: 3.1
Posted by: Suprotim Agarwal, on 1/25/2009, in category "ASP.NET 2.0 & 3.5"
Views: this article has been read 20937 times
Abstract: I had recently posted an article ASP.NET TreeView and SiteMap : 5 Common Tips. A viewer mailed me back asking if it was possible to create a SiteMap dynamically and add it to a TreeView. This short and simple article demonstrates how to create an ASP.NET SiteMap file dynamically and bind it to a TreeView control.

Creating an ASP.NET SiteMap dynamically using LINQ and bind to a TreeView
 
I had recently posted an article ASP.NET TreeView and SiteMap : 5 Common Tips. A viewer mailed me back asking if it was possible to create a SiteMap dynamically and add it to a TreeView. This short and simple article demonstrates how to create an ASP.NET SiteMap file dynamically and bind it to a TreeView control.
SiteMap is an XML file. You can use both the System.XML.Linq.XDocument and System.XML.Linq.XElement classes to create XML.  When you need to create an XML document containing XML declaration, XML Document Type (DTD), Processing instructions, Comments or Namespaces, you should go in for the XDocument class. Here’s how to create and save a SiteMap file dynamically using LINQ
Drag and drop a Button and a TreeView control from the toolbox to the Default.aspx page
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="btnCreate" runat="server"
            Text="Create and Bind" />
        <br />
        <br />
        <asp:TreeView ID="TreeView1" runat="server">
        </asp:TreeView>
    </div>
    </form>
</body>
Now add the following code on the click event of the button
C#
    protected void btnCreate_Click(object sender, EventArgs e)
    {
        XNamespace siteNM = "http://schemas.microsoft.com/AspNet/SiteMap-File-1.0";
 
        XDocument xDoc = new XDocument(
                    new XDeclaration("1.0", "UTF-8", null),
                    new XElement(siteNM + "siteMap",
                        new XElement(siteNM + "siteMapNode", new XAttribute("title", "My Favorites"),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "Favorite Sites"),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "ASP.NET Home"), new XAttribute("url", "http://www.asp.net")),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "ASP.NET Articles"), new XAttribute("url", "http://www.dotnetcurry.com")),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "Windows Client"), new XAttribute("url", "http://www.windowsclient.net")),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "Silverlight"), new XAttribute("url", "http://silverlight.net"))
                            ),
 
                        new XElement(siteNM + "siteMapNode", new XAttribute("title", "Favorite Blogs"),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "ScottGu Blog"), new XAttribute("url", "http://weblogs.asp.net/scottgu"),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "Technology Blog"), new XAttribute("url", "http://www.devcurry.com")),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "SQL Blog"), new XAttribute("url", "http://www.sqlservercurry.com")),
                            new XElement(siteNM + "siteMapNode", new XAttribute("title", "Food Lovers"), new XAttribute("url", "http://foodatarian.com"))
                            )) )                          
                           
                            ));
      
       
        // Save to Disk
        xDoc.Save(Server.MapPath("web.sitemap"));
       
    }
VB.NET
        Protected Sub btnCreate_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim siteNM As XNamespace = "http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"
 
        Dim xDoc As New XDocument(New XDeclaration("1.0", "UTF-8", Nothing), _
          New XElement(siteNM + "siteMap", _
                       New XElement(siteNM + "siteMapNode", New XAttribute("title", "My Favorites"), _
                                    New XElement(siteNM + "siteMapNode", New XAttribute("title", "Favorite Sites"), _
                                                 New XElement(siteNM + "siteMapNode", New XAttribute("title", "ASP.NET Home"), New XAttribute("url", "http://www.asp.net")), _
                                                 New XElement(siteNM + "siteMapNode", New XAttribute("title", "ASP.NET Articles"), New XAttribute("url", "http://www.dotnetcurry.com")), _
                                                 New XElement(siteNM + "siteMapNode", New XAttribute("title", "Windows Client"), New XAttribute("url", "http://www.windowsclient.net")), _
                                                 New XElement(siteNM + "siteMapNode", New XAttribute("title", "Silverlight"), New XAttribute("url", "http://silverlight.net"))), _
                                    New XElement(siteNM + "siteMapNode", New XAttribute("title", "Favorite Blogs"), _
                                                 New XElement(siteNM + "siteMapNode", New XAttribute("title", "ScottGu Blog"), New XAttribute("url", "http://weblogs.asp.net/scottgu"), _
                                                              New XElement(siteNM + "siteMapNode", New XAttribute("title", "Technology Blog"), New XAttribute("url", "http://www.devcurry.com")), _
                                                              New XElement(siteNM + "siteMapNode", New XAttribute("title", "SQL Blog"), New XAttribute("url", "http://www.sqlservercurry.com")), _
                                                              New XElement(siteNM + "siteMapNode", New XAttribute("title", "Food Lovers"), New XAttribute("url", "http://foodatarian.com")))))))
 
 
        ' Save to Disk
        xDoc.Save(Server.MapPath("web.sitemap"))
    End Sub
 
Note: As you might have observed, I have added a namespace for each element. Here all elements use one namespace. In case you don't add a namespace for one parent element, it will add a empty namespace (xmlns=””) and the compiler will raise a warning “The element 'siteMap' in namespace 'http://schemas.microsoft.com/AspNet/SiteMap-File-1.0' has invalid child element 'siteMapNode’ “. Hence the trick is to add a namespace for each element.
Once the SiteMap is created, in order to bind it to the TreeView, all that is needed is to create a SiteMapDataSource and bind it to the TreeView
C#
...
        // Save to Disk
        xDoc.Save(Server.MapPath("web.sitemap"));
        if(File.Exists(Server.MapPath("web.sitemap")))
        {          
            TreeView1.DataSource = new SiteMapDataSource();
            TreeView1.DataBind();
        }
VB.NET
...
 
        ' Save to Disk
        xDoc.Save(Server.MapPath("web.sitemap"))
        If File.Exists(Server.MapPath("web.sitemap")) Then
            TreeView1.DataSource = New SiteMapDataSource()
            TreeView1.DataBind()
        End If
The result is a dynamically created SiteMap bound to a TreeView control
Dynamic TreeView
I hope you liked the article and I thank you for viewing it.









Page copy protected against web site content infringement by Copyscape


How would you rate this article?

User Feedback
Comment posted by SnovvWolf on Wednesday, February 25, 2009 3:31 PM
This article explains how to create and save an xml file, and then how to bind it to a treeview, but I think it falls far short of what the title promises. The xml is populated using hardcoded urls. (Which would be totally fine for an example that wasn't titled "Creating an ASP.NET SiteMap dynamically..."

I would have expected that this should contain a routine that accepts a starting url and then traverses the website and picks up the website hierarchy "dynamically" and construct the xml accordingly.

Why would anyone hand-code an xml file as proposed above? Look ma, I'm linq'ing.

I'm rating this 3 just because there's some value to the article, just not the intended value. It's misleading.

For 5 stars, rename it to "How to bind xml to a treeview with 2 lines of code + 40 lines of code you should ignore".
Comment posted by Suprotim Agarwal on Thursday, February 26, 2009 6:36 AM
SnovvWolf: Thanks for your comments. Apologies if the title was misleading but the intention was to show how to create a SiteMap using LINQ and bind it to a TreeView. Usually a SiteMap would depict links within the site. However the scenario of fetching links dyanamically is not too difficult to achive and especially with LINQ, it shouldn't be much of a pain either.

Watch out for another article in a couple of days which will show how to query the sitemap using LINQ. I do not know if I will cover fetching the url's dynamically, but it's going to be an interesting read!
Comment posted by PA on Friday, October 09, 2009 6:10 AM
I tried the code. The sitemap file get's created, by there's an exception [Object reference not set to an instance of an object] for
TreeView1.DataSource = new SiteMapDataSource();

Any help there ?
Comment posted by RF on Thursday, December 10, 2009 5:12 AM
dddd
Comment posted by annoyed on Friday, June 11, 2010 5:06 AM
Why you titled it "Creating an ASP.NET SiteMap dynamically using LINQ and bind to a TreeView" is beyond me. Theres nothing dynamic about it. You've hard coded the whole thing. Thx for wasting my time!

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel

NEWSLETTER