[RESOLVED] Adding a sitemapnode

I need to add a sitemapnode to my screen when the user opens it without adding an actual sitemapnode to the sitemap file.  This node needs to include url, title, and description.  Does anyone have code to show how to do this in C#? 

add a file called  'Web.sitemap' with this code:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
	<siteMapNode title="Home" url="~/Default.aspx">
		<siteMapNode url="~/description.aspx" title="description">
						<siteMapNode url="~/DetailsPage.aspx"/>



add a class names 'SmartSiteMapProvider.cs' with this code:

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Specialized;

/// <summary>
/// Summary description for SmartSiteMapProvider
/// </summary>
public class SmartSiteMapProvider : XmlSiteMapProvider
    public override void Initialize(string name, NameValueCollection attributes)
        base.Initialize(name, attributes);
        this.SiteMapResolve += new SiteMapResolveEventHandler(SmartSiteMapProvider_SiteMapResolve);

    //this solves the spaces in querystring
   public override System.Web.SiteMapNode FindSiteMapNode(System.Web.HttpContext context)
            SiteMapNode node = base.FindSiteMapNode(context);

            if (node == null)
                if (context == null)
                    return null;

                string queryString = ((Page)context.CurrentHandler).ClientQueryString;

                string pageUrl = HttpUtility.UrlDecode(context.Request.Path + "?" + queryString);
                node = base.FindSiteMapNode(pageUrl);

            return node;

   SiteMapNode SmartSiteMapProvider_SiteMapResolve(object sender, SiteMapResolveEventArgs e)

        if (SiteMap.CurrentNode == null) return null;

        SiteMapNode tempNode = SiteMap.CurrentNode;
        while (tempNode != null)
            string qs = GetReliance(tempNode, e.Context);
            if (qs != null)

                tempNode.ReadOnly = false;
                tempNode.Url += qs;
                tempNode.ReadOnly = true;
            tempNode = tempNode.ParentNode;

        return SiteMap.CurrentNode;

    private void RemoveQuery(SiteMapNode parent)
        int pos = parent.Url.IndexOf('?');
        if (pos != -1)
            parent.ReadOnly = false;
            parent.Url = parent.Url.Remove(pos);
            parent.ReadOnly = true;
        foreach (SiteMapNode child in parent.ChildNodes)

    private string GetReliance(SiteMapNode node, HttpContext context)
        //Check to see if the node supports reliance
        if (node["reliantOn"] == null)
            return null;

        NameValueCollection values = new NameValueCollection();
        string[] vars = node["reliantOn"].Split(",".ToCharArray());

        foreach (string s in vars)
            string var = s.Trim();
            //Make sure the var exists in the querystring
            if (context.Request.QueryString[var] == null)

            values.Add(var, context.Request.QueryString[var]);

        if (values.Count == 0)
            return null;

        return NameValueCollectionToString(values);

    private string NameValueCollectionToString(NameValueCollection col)
        string[] parts = new string[col.Count];
        string[] keys = col.AllKeys;

        for (int i = 0; i < keys.Length; i++)
           // parts[i] = keys[i] + "=" + col[keys[i]];
            parts[i] = keys[i] + "=" + col[keys[i]];
            string url = "?" + String.Join("&", parts);
        return url;
        url = "";


add a header.ascx control with this code:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="header.ascx.cs" Inherits="header" %>

<div id="trackback">
  <asp:SiteMapPath ID="SiteMapPath1" runat="server" Enabled="true" EnableViewState="true"
                PathSeparator=" > " PathDirection="RootToCurrent" 
    <PathSeparatorStyle Font-Bold="False" ForeColor="Black" />
    <RootNodeStyle  />
    <CurrentNodeStyle  />
    <NodeStyle  />

and on top of each aspx page where do you want the sitemap, include this code:

         //for sitemap
        SiteMap.SiteMapResolve +=
         new SiteMapResolveEventHandler(siteMap_SiteMapResolve);


This is all you need to do. Good luck!!

It's easy enough to create notes, but the trouble is the node collection is read only. Rather than creating a new provider, two solutions spring to mind:

  1. Just use a plan old hyperlink, but place it above the menu and style it so it looks as though it's part of the menu. This might not work for you, depending upon where you need the menu item to appear.
  2. Add the site map node to the site map and use a SiteMapResolve event to change the node details. DO NOT hook up the resolve event in each page; it's a static event and should only be defined once per application, so use Application_Start in global.asax for this.

Both of these do rely on the node you want to add being in a set place. If that's not the case (ie it's added in a different place depending upon the current menu) then you'd probably have to create a new provider.

thoughts on "[RESOLVED] Adding a sitemapnode"

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>