In this article, I will show you how you can avoid session loss when using Site maps in your website that is configured to use cookieless sessions.
The problem will occur when you use SiteMap files in a website that is configured to use cookie-less sessions. In that case, the SiteMap provider will not insert the session ID in the returned nodes that were populated from the SiteMap file, and so any navigation control (e.g.,
Menu) that uses the SiteMap provider will have items that don't contain the session ID, and so, when the user navigates your website using those controls, the user session will be lost on every navigation.
Using the code
There are many solutions for the above mentioned problem. One simple solution is to handle the databound events for the navigation control and fix the URLs that are generated in the control.
For example, if you are using a
TreeView control, you can handle its
protected void TreeView1_TreeNodeDataBound(object sender, TreeNodeEventArgs e)
Note that the
ApplyAppPathModifier method will automatically insert the session ID to the URL.
For more information on how to apply the mentioned solution, see my blog post here.
Handling the control databound events will be a simple solution, but it could not be a practical one especially when you are working with many SiteMap files and many navigation controls. In that case, you will need to handle every control event.
The other solution is to inherit from the
XmlSiteMapprovider class and override some properties and functions; see the custom provider code below:
Public Class SiteMapProviderForCookieeLessSessions
Public Overrides ReadOnly Property CurrentNode() As System.Web.SiteMapNode
Dim cn As SiteMapNode = MyBase.CurrentNode.Clone()
Public Overrides ReadOnly Property RootNode() As System.Web.SiteMapNode
Dim Root As SiteMapNode = MyBase.RootNode.Clone()
Public Overrides Function GetParentNode(ByVal node As _
System.Web.SiteMapNode) As System.Web.SiteMapNode
Dim ParentNode As SiteMapNode = MyBase.GetParentNode(node).Clone()
Public Overrides Function GetChildNodes(ByVal node As _
System.Web.SiteMapNode) As System.Web.SiteMapNodeCollection
Dim CurrentChilds As SiteMapNodeCollection = MyBase.GetChildNodes(node)
Dim ModifiedChilds As New SiteMapNodeCollection()
For Each tnode As SiteMapNode In CurrentChilds
Dim cnode As SiteMapNode = tnode.Clone()
Private Sub ProcessUrl(ByVal node As SiteMapNode)
If node.Url.Length > 0 Then
If Not HttpContext.Current Is Nothing AndAlso _
Not HttpContext.Current.Response Is Nothing Then
node.Url = HttpContext.Current.Response.ApplyAppPathModifier(node.Url)
In the mentioned code, there is a private function
ProcessUrl which is used to fix the URLs of the returned nodes. For more information about the overriden properties and methods, see the MSDN documentation for the
I attached the
CustomProvider code as a separate class project. Also, I created a demo website which contains two menu controls, one that uses the default provider which doesn't append the session ID in the generated nodes, and another menu that uses the custom provider which handles this issue perfectly. The website that I included is configured to use cookie-less sessions from the web.config file, and also, I registered the custom provider in the web.config file under the