使用 XML Sitemap Provider 进行无 Cookie 会话时避免会话丢失






3.86/5 (5投票s)
本文将解释在使用 XML Sitemap Provider 的无 Cookie 会话时如何避免会话丢失。
引言
在本文中,我将向您展示在使用配置为使用无 Cookie 会话的网站中的站点地图时,如何避免会话丢失。
背景
默认情况下,ASP.NET 使用 Cookie 来记住请求之间的用户会话。但是,在使用无 Cookie 会话时,会话 ID 不会存储在 Cookie 中;相反,运行时会将 Session ID 插入到页面 URL 中,以便在用户提交页面时可以提取该 ID。 请参阅下面的图像,了解 ID 的外观
当您在配置为使用无 Cookie 会话的网站中使用 SiteMap 文件时,会出现问题。 在这种情况下,SiteMap 提供程序不会将会话 ID 插入到从 SiteMap 文件填充的返回节点中,因此,任何使用 SiteMap 提供程序的导航控件(例如,TreeView
、Menu
)都将具有不包含会话 ID 的项目,因此,当用户使用这些控件导航您的网站时,每次导航都会丢失用户会话。
使用代码
对于上述问题,有许多解决方案。 一种简单的解决方案是处理导航控件的 databound 事件并修复控件中生成的 URL。
例如,如果您使用的是TreeView
控件,则可以处理其NodeDataBound
事件。
protected void TreeView1_TreeNodeDataBound(object sender, TreeNodeEventArgs e)
{
e.Node.NavigateUrl =
HttpContext.Current.Response.ApplyAppPathModifier(e.Node.NavigateUrl);
}
请注意,ApplyAppPathModifier
方法会自动将会话 ID 插入到 URL 中。
有关如何应用上述解决方案的更多信息,请参阅我的博客文章此处。
处理控件 databound 事件将是一个简单的解决方案,但当您使用许多 SiteMap 文件和许多导航控件时,它可能不是一个实用的解决方案。 在这种情况下,您需要处理每个控件事件。
另一个解决方案是从XmlSiteMapprovider
类继承并覆盖一些属性和函数;请参见下面的自定义提供程序代码
Imports System.Web
Public Class SiteMapProviderForCookieeLessSessions
Inherits XmlSiteMapProvider
Public Overrides ReadOnly Property CurrentNode() As System.Web.SiteMapNode
Get
Dim cn As SiteMapNode = MyBase.CurrentNode.Clone()
ProcessUrl(cn)
Return cn
End Get
End Property
Public Overrides ReadOnly Property RootNode() As System.Web.SiteMapNode
Get
Dim Root As SiteMapNode = MyBase.RootNode.Clone()
ProcessUrl(Root)
Return Root
End Get
End Property
Public Overrides Function GetParentNode(ByVal node As _
System.Web.SiteMapNode) As System.Web.SiteMapNode
Dim ParentNode As SiteMapNode = MyBase.GetParentNode(node).Clone()
ProcessUrl(ParentNode)
Return ParentNode
End Function
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()
ProcessUrl(cnode)
ModifiedChilds.Add(cnode)
Next
Return ModifiedChilds
End Function
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)
End If
End If
End Sub
End Class
在上述代码中,有一个私有函数ProcessUrl
,用于修复返回节点的 URL。 有关覆盖属性和方法的更多信息,请参阅MSDN 文档,了解XMLSiteMapprovider
成员。
我将CustomProvider
代码作为单独的类项目附加。 此外,我创建了一个演示网站,其中包含两个菜单控件,一个使用默认提供程序,该提供程序不会在生成的节点中附加会话 ID,另一个菜单使用自定义提供程序,该提供程序可以完美地处理此问题。 我包含的网站配置为从web.config文件使用无 Cookie 会话,并且我还SiteMap
在web.config文件的部分下注册了自定义提供程序。