3

I've got a custom menu navigation built from a web.sitemap file, the first line of this would be something like:

SiteMapNodeCollection topLevelNodes = SiteMap.RootNode.ChildNodes;

This works - it gets all the top level nodes from the web.sitemap file, and allows me to look through each SiteMapNode and do stuff.

However, now I want to be able to create multiple web.sitemap files, and then programmatically determine which web.sitemap file to use, but I can't seem to find out how to do this. I'm assuming I could either create one custom SiteMapProvider that can perform the logic to determine which web.sitemap file to load, or I have multiple providers, each one with the SiteMapFile property set to a specific *.sitemap file, and then switch providers programmatically before I access SiteMap.RootNode.

I think it's probably easier to have one custom provider, and then override the part where it looks for the actual physical sitemap file location, but I'm unclear how I would do this

I've googled a lot, but most answers seem to be regarding the standard sitemappath controls and so on, and how to set a SiteMapDataSource, which I don't think is relevant to my approach.

Andrew Johns
  • 705
  • 1
  • 6
  • 26
  • 4
    You shouldn't switch/change anything... instead you need to access the RootNode like this all the time *SiteMap.Providers[someProvider].RootNode* and the *someProvider* should then be resolved at runtime. – Pauli Østerø Jan 25 '11 at 21:44
  • ooh, never thought of that, I will try that tomorrow, that sounds like it would work. – Andrew Johns Jan 25 '11 at 21:50

2 Answers2

3

First you need to specify all of your sitemap files in your web.config as such:

<siteMap defaultProvider="FNDSiteMap" enabled="true">
  <providers>
    <add name="FNDSiteMap" type="System.Web.XmlSiteMapProvider" siteMapFile="FND.sitemap" securityTrimmingEnabled="true"/>
    <add name="STASiteMap" type="System.Web.XmlSiteMapProvider" siteMapFile="STA.sitemap" securityTrimmingEnabled="true"/>
    <add name="TASiteMap" type="System.Web.XmlSiteMapProvider" siteMapFile="TA.sitemap" securityTrimmingEnabled="true"/>
  </providers>
</siteMap>

Then in your code-behind you can dynamically assign your SiteMapDataSource (which is bound to your menu) to one of the providers you specified in your web.config:

.aspx

<asp:Menu ID="MenuLevel1" runat="server" Orientation="Horizontal" DataSourceID="SiteMapLevel1"
    MaximumDynamicDisplayLevels="0" IncludeStyleBlock="false">
</asp:Menu>                
<asp:SiteMapDataSource ID="SiteMapLevel1" runat="server" /> 

.cs

SiteMapLevel1.SiteMapProvider = "TASiteMap";
e36M3
  • 5,952
  • 6
  • 36
  • 47
  • 1
    this would be ideal if I was using an Asp:menu control which had a SiteMapDataSource property, but this is custom code that isn't using an asp:menu control. What you're suggesting sounds like I would need to convert my code into an custom control that extends asp:menu? I'm going to try Pauli's suggestion in his comment above first. – Andrew Johns Jan 25 '11 at 21:52
3

Pauli's comment was the answer to my particular requirement:

"You shouldn't switch/change anything... instead you need to access the RootNode like this all the time SiteMap.Providers[someProvider].RootNode and the someProvider should then be resolved at runtime."

I hadn't realised this was possible, but was the correct solution for me.

Mazdak Shojaie
  • 1,620
  • 1
  • 25
  • 32
Andrew Johns
  • 705
  • 1
  • 6
  • 26