|
修改提供程序(Provider)返回的站点导航数据
存储在web.sitemap中、供XmlSiteMapProvider使用的导航数据是静态的--这些数据被载入内存中并作为只读数据存储。但是,很多站点的导航结构是根据查询字符串的值来参数化的。例如,新闻组(newsgroup)站点可能拥有良好定义的页面结构(例如,主页、新闻类别页面和新闻内容页面),但是实际的内容可能会有很大的不同,这依赖于查询字符串中的标识符。尽管把每种可能的查询字符串值都存储在<siteMapNode>元素中也是可能的,但是即使是中等数量的查询字符串值,也要求sitemap文件包含数百个<siteMapNode>元素。
站点导航特性在SiteMapProvider基类中暴露了SiteMapResolve事件。可以使用SiteMap.SiteMapResolve或直接使用提供程序SiteMap.Provider.SiteMapResolve来执行这个事件。这个事件的返回值是一个SiteMapNode实例。你可以在自己的事件处理程序中编写自定义逻辑来建立SiteMapNode实例的层次结构。这个逻辑可以修改每个SiteMapNode的属性,因此URL和Title等属性会反映查询字符串带有的数据信息。
下面的例子在global.asax中注册了一个事件处理程序。这个事件处理程序的代码是App_Code目录中的一个类。这个自定义的类复制与当前页面对应的SiteMapNode实例。XmlSiteMapProvider返回的节点都是只读的,而调用SiteMapNode上的Clone方法返回的是可写入的节点。在实例中,如果给Clone传递了true值,将导致当前的SiteMapNode和它的所有父节点都是可写入的。这个类的代码的其它部分检查当前的页面和当前页面的查询字符串,确定当前页面位于站点层次结构的什么位置。代码修改了URL和Title属性,包含一些额外的信息,这样SiteMapPath控件显示的导航UI就反映了网站用户为到达当前页面的实际点击路径。
运行示例的时候,你开始位于站点的主页。SiteMapPath控件也反映了这一点。点击任何链接都会带你进入分类页面,它显示相关新闻类别中的新闻链接。请注意,如果你把鼠标停留在SiteMapPath控件的最后一个链接上,浏览器状态栏中显示的URL包含了查询字符串信息(它指定了新闻类别)。点击任何一个发布链接都会把你带回到新闻发布页面。如果你把鼠标停留SiteMapPath控件的链接上,可以注意到控件中的最后两个链接带有的URL和Title包含了点击路径的正确查询字符串和描述信息。如果你导航到站点的主页,并点击其它的新闻组和内容链接,SiteMapPath控件会被更新并反映第二次点击的链接。
以下是引用片段: Public Class PathExpansionHandler Public Shared Function ExpandPath(ByVal sender As Object, ByVal e As SiteMapResolveEventArgs) As SiteMapNode '获取当前和之前节点的引用 Dim nodeCopy As SiteMapNode = SiteMap.CurrentNode.Clone(True) Dim tempNode As SiteMapNode = nodeCopy
'Check if there is a newsgroup type in the query string Dim typeID As String = Nothing Dim typeIDUrlEncoded As String = Nothing If Not String.IsNullOrEmpty(e.Context.Request.QueryString("type")) Then typeID = e.Context.Server.HtmlEncode(e.Context.Request.QueryString("type")) typeIDUrlEncoded = e.Context.Server.UrlEncode(e.Context.Request.QueryString("type")) End If
'首先执行发布页面URL的固定 '如果查询字符串中包含发布ID,我们就知道当前节点式发布页面 If Not String.IsNullOrEmpty(e.Context.Request.QueryString("postingID")) Then Dim postingID as string = _ e.Context.Server.HtmlEncode(e.Context.Request.QueryString("postingID")) Dim postingIDUrlEncoded as string = _ e.Context.Server.UrlEncode(e.Context.Request.QueryString("postingID")) Dim NewUrl As String = tempNode.Url + "?type=" + typeIDUrlEncoded + "&postingID=" + postingIDUrlEncoded Dim NewTitle As String = tempNode.Title + ": " + postingID tempNode.Url = NewUrl tempNode.Title = NewTitle
tempNode = tempNode.ParentNode End If
'然后,对新闻组页面进行固定 '这时候nodeCopy 变量知贤了新闻组节点 If Not String.IsNullOrEmpty(e.Context.Request.QueryString("type")) Then Dim NewUrl As String = tempNode.Url + "?type=" + typeIDUrlEncoded Dim NewTitle As String = tempNode.Title + ": " + typeID tempNode.Url = NewUrl tempNode.Title = NewTitle End If
'最后返回当前节点 Return nodeCopy End Function End Class | |