ASP.NET 2.0 and Site Maps

I hereby interrupt the “week of the malcontent” with the “evening of possible enlightenment”.

The provider design pattern in ASP.NET 2.0 is sweet. I’ve been toying around in the SiteMapProvider area since the first CTP. There is an XmlSiteMapProvider which let’s you describe the navigation and layout of your web site in an XML file like so:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap>
  <siteMapNode title="Home" url="Default.aspx" >
    <siteMapNode title="Products" url="Products.aspx">
      <siteMapNode title="Seafood" url="Seafood.aspx"/>
      <siteMapNode title="Produce" url="Produce.aspx"/>
    </siteMapNode>
    <siteMapNode title="Contact" url="Contact.aspx">
      <siteMapNode title="Email Us" url="Email.aspx"/>
      <siteMapNode title="Phone List" url="Phones.aspx" />
    </siteMapNode>
  </siteMapNode>
</siteMap>

Without writing a line of code (just some drag and drop operations), you can give all the pages in your site a tree view of the site hierarchy and a bread crumb control:

What if your site navigation comes from a database table?

NodeID URL           Name     ParentNodeID 
------ ------------- -------- ------------ 
1      Default.aspx  Home     0
2      Products.aspx Products 1
3      Seafood.aspx  Seafood  2
4      Produce.aspx  Produce  2
5      Contact.aspx  Contact  1
6      Email.aspx    Email    5
7      Phones.aspx   Phone    5

All you need to do is derive from the abstract class SiteMapProvider and override a handful of methods, like GetParentNode and GetChildNodes. These methods can be straightforward to implement with a few pre-built collections of type Dictionary<string, SiteMapNode>. SiteMapNode objects represent the nodes in the site map, while a Dictionary is one of the exciting new classes from the System.Collections.Generic namespace, which you can use to build strongly typed collections.

One you have some code querying SQL Server and implementing the SiteMapProvider methods, you just need to tell the runtime about your new provider via a config file:

<siteMap defaultProvider="MySqlSiteMapProvider" enabled="true"> 
  <providers> 
    <add name="MySqlSiteMapProvider" type="SqlSiteMapProvider"
         connectionStringKey="ConnectionString"/> 
  </providers> 
</siteMap> 

You can have multiple providers for a site. If half of the site navigation information comes from XML and the other half from the database, that’s quite possible. It will be interesting to see what other providers come out. I'm sure SQL, and File System providers will be in demand.

Print | posted @ Thursday, July 08, 2004 5:05 AM

Comments on this entry:

Gravatar # re: ASP.NET 2.0 and Site Maps
by Sharad Kumar at 9/19/2004 6:20 PM

Hi Scott,
<br>
<br>Sitemaps are undoubtedly cool. I've tried to find info on merging of two sitemaps, but found none in SDK or MSDN. Even when we add another Provider, only one at a time is active/default. How to setup hierarchy within them? Any direction shall be outstanding. Thanks in advance!
<br>
<br>--
<br>Sharad
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by Scott Allen at 9/21/2004 5:13 PM

Hi Sharad:
<br>
<br>I'll have to give this a try over the next couple weeks and see what I come up with. I have a provider written for SQL Server, so I'll try combining the Xml and the SQL providers.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by Randall at 11/11/2004 9:07 PM

Hi Scott. Did you ever get the SQL SiteMapProvider working? I was wondering If I might peek at the code?
<br>
<br>thx, -R
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by Scott Allen at 11/11/2004 9:12 PM

Yes I did, send me an email (scott AT odetocode.com) or ping me on MSN IM (bitmask AT yahoo.com) and I'll hand it over.
  
Gravatar # SitemapProvider or DataSource for Menu?
by wyx2000 at 12/18/2004 8:01 AM

I am not sure if I misunderstand something here, I create a HierarchicalDataSource to read sitemap from my db(now read from my another class since I need the sitemap in another place too), But I am not sure if it is the sitemapprovider you are talking about here. I think not, does the provider you are talking here can replace the embed sitemapprovider? that means you can just put a SiteMapDataSource on your page, and the sitemap is from your provider? and when you call SiteMap.CurrentNode, the property is actually from your provider? if it, great then, can I have some articles about it?
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by wyx2000 at 12/18/2004 8:02 AM

Sorry, leave my email, hope someone can point me the right direction.
<br>
<br>wyx1999@hotmail.com
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by automation at 1/5/2005 7:32 AM

Here we are 2005, great tool being created, and there is no autocreation of a sitemap?
<br>
<br>Also - where is the browse to the sitemap?
<br>
<br>Just seems half baked by Microsoft.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by Sky Sigal at 3/7/2005 3:51 PM

Hello Scott:
<br>
<br>I see that you were going to try to combine two different site.maps into one:
<br>
<br>&quot;I have a provider written for SQL Server, so I'll try combining the Xml and the SQL providers.&quot;
<br>
<br>I was just wondering if you succeeded at this, and care to share any insights, as as I'm getting no successes here trying to mix an xml site map mixed with a file directory based site map provider :-(
<br>
<br>
<br>
<br>Thanks so much!
<br>
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by rap at 5/7/2005 1:17 AM

I have test it and don't run :(
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by Ali at 8/9/2005 9:49 AM

I'm Struggling with the concept of SiteMapProvider and the implementation of the SiteMap Path control !

What's the easiest and basic way to implement it and provide a ready-made Provider for it ?

"Any Clues ! Links ! are appreciated " !
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by scott at 8/9/2005 5:38 PM

I know there is not much out there, Ali.

You can look at the sample "SimpleTextSiteMapProvider" provided in the docs: http://msdn2.microsoft.com/library/e52te4hd(en-us,vs.80).aspx

Other than that, the way I learned the most about the SiteMapProvider was by using Reflector to view the source code in System.Web.dll : http://www.aisto.com/roeder/dotnet/
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by George Cosoveanu at 11/8/2005 10:23 PM

Hi Scott,

I managed to implement a SQL server SiteMap provider and it is working.
However, when I am making a change in SQL Server in the SiteMap table, it is not reflected on the page when I do a refresh (I even set SQL Cache invalidation on my SQL Server 2000 database). Only when I close and re-open the Visual Web Developer 2005 the change appears on the page.
Any idea how to fix this?

Thanks,
George
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by scott at 11/11/2005 2:32 PM

Hi George:

Does this happen on a web page or in the designer? If it is the desginer I'm not sure what to do - I'll have to experiment.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by sloan at 12/10/2005 4:35 AM



I have seem to found a small issue with the nesting.

My default Web.sitemap file:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="schemas.microsoft.com/.../SiteMap-File-1.0" >
<siteMapNode title="Everybody Stuff" url="thisDoesntReallyExistButCausesAnIssueIfIRemoveIt.aspx">
<siteMapNode url="everybody1.aspx" title="Everybody1" description="MyWeb1" />
<siteMapNode url="everybody2.aspx" title="Everybody2" description="MyWeb2" />
</siteMapNode>
</siteMap>



Ok, then I have another sitemap file.

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="schemas.microsoft.com/.../SiteMap-File-1.0" >
<siteMapNode title="hidden root" description="hidden root">

<siteMapNode url="~/UserData/UserInfoViewAll.aspx" title="View All Users" description="View Users" />
<siteMapNode url="~/UserData/UserInfoManage.aspx" title="Manage Users" description="Manager Users in the System" />

<siteMapNode siteMapFile="~/web.sitemap" />
</siteMapNode>
</siteMap>



Notice that I nest "Web.sitemap" into the second file.


If I leave the "url" attribute for "Everybody Stuff", the menu displays as I would predict.

If I remove this xml attribute
( url="thisDoesntReallyExistButCausesAnIssueIfIRemoveIt.aspx" )
(as in , I take it out completely),
the resultant menu doesn't show any of the "everybody stuff" items.

I've tried several things to get it show up, to no avail.

..

FYI, I also implemented a custom XmlSiteMapProvider. This checks my custom IPrincipal object to see if the use is or isn't in certain roles. I'll post that code, and the corresponding web.config also.

public class GranadaCoderSecureMapProvider : XmlSiteMapProvider
{
public GranadaCoderSecureMapProvider()
{

}


public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
{
//return base.IsAccessibleToUser(context, node);
string currentURL = node.Url;


if (currentURL.Length > 0)
{
//custom functionality here

// here is a simple substitution
return true;

}
return true;



}

}

And web.config section, dealing with this.

<system.web>


<siteMap defaultProvider="XmlSiteMapProvider">
<providers>
<add name="XmlSiteMapProvider" type="System.Web.XmlSiteMapProvider" siteMapFile="~/Web.sitemap" securityTrimmingEnabled="true" />
<add name ="Company1SiteMap" type ="GranadaCoderSecureMapProvider" siteMapFile="~/Sitemaps/confirmedUsers.sitemap" securityTrimmingEnabled="true" />
</providers>
</siteMap>


So, I'm trying to figure out if/why I'm not getting the expected results.

If anyone sees something screwball in my setup, let me know.
I guess this is kinda new territory (Dec 2005), and there isn't alot on the web about this stuff yet, especially the nesting.

Thanks.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by scott at 12/10/2005 5:06 AM

Sloan: I have not tried nesting as yet, I'll have to take a look at this.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by sloan at 12/13/2005 4:43 AM

Ok, thanks. I'll check back in a few days.
..
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by sloan at 1/9/2006 1:57 AM


Scott, I was hoping now that New Year has past you might be able to check the issue I reported.
Thanks.

  
Gravatar # re: ASP.NET 2.0 and Site Maps
by Ryan at 1/10/2006 9:40 PM

I have converted the MSDN C# SQLSiteMapProvider (msdn.microsoft.com/.../default.asp) to VB.NET if anyone is interested in checking it out.

It works fine, only trouble I am having now is that it caches the sitemap for waaaaaay to long.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by docluv at 1/20/2006 2:56 PM

Ryan,

I am trying to get a VB version of the SQL Provider working from that article right now. It only shows the first node and its children, no siblings.
I have a thread on asp.net, http://forums.asp.net/1173914/ShowPost.aspx
Any help you could provide would be great.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by scott at 1/22/2006 3:12 AM

Have you considered pushing all of your sibling nodes underneath a top level node? The site map data source controls can always be configured to hide the top node from navigation menus and such.
  
Gravatar # re: ASP.NET 2.0 and Site Maps
by Leo at 2/16/2006 9:44 AM

Hi Scott,

I tried SqlSiteMapProvider in Visual Studio 2005 and tested direclly in design mode, i found something strange, that is,
I created two roles to get different site map item, when the first role login and get the right top level and sub-level menus, then logout and re-login with the other role, the sub-level menus will be cached the same as the first role's. If I run again with debug point in code, it will get the correct sub-level menus, I had clear cache stuffs in browser, where is the issue comes from ?

Leo
  
Comments have been closed on this topic.