65.9K
CodeProject 正在变化。 阅读更多。
Home

更好的 SiteMapResolve

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (10投票s)

2006年3月1日

3分钟阅读

viewsIcon

90638

downloadIcon

884

描述了如何创建一个更有用的 SiteMapResolve 事件。

引言

我最近一直在开发一个 ASP.NET 2.0 网站,并使用新的站点地图功能来实现菜单和面包屑导航功能。 然而,我需要为特定页面动态地修改站点地图结构。

其他尝试过此操作的人可能知道 SiteMap.SiteMapResolve 事件,该事件可用于动态构造站点地图节点。 但是,此事件有一个相当令人恼火的设计缺陷 - 它是 static。 因此,将事件处理程序附加到它将导致在每个请求上调用该处理程序(实际上,对于访问 SiteMap.CurrentNode 属性的每个请求)。

本文介绍了一个 ASP.NET 2.0 页面的基类,该基类提供特定于页面的 SiteMapResolve 事件。 继承自此基类的页面可以简单地挂钩到此事件,并自由地修改站点地图结构,因为知道这些更改只会影响该页面的当前请求。

使用代码

在你进一步操作之前,运行示例项目并特别注意以下内容

  • 诸如“联系我们”和“常见问题解答”之类的页面在站点地图文件中列出。
  • NewsItem.aspx 页面未在站点地图文件中列出。 因此,它不会出现在菜单中。 主页上有三个指向新闻项的链接,这是访问 NewsItem.aspx 页面最简单的方法。
  • 当您查看新闻项时,会显示一个直观的面包屑导航 - 此面包屑导航是动态构造的站点地图节点的结果。

最重要的类型是 PageBase 类。 此类继承自 System.Web.UI.Page 并添加一个 SiteMapResolve 事件,该事件仅针对该页面触发。 要使用该类,只需声明您的页面继承自它,如下所示

public partial class NewsItem : Support.PageBase

一旦您继承了 PageBase,您就可以以通常的方式挂钩到 SiteMapResolve 事件

protected override SiteMapNode OnSiteMapResolve(SiteMapResolveEventArgs e)
{
    //construct and return your custom SiteMapNode 

    //here - see download for example code

}

上面,我提到 PageBase.SiteMapResolve 事件仅针对处理它的特定页面触发。 这并不完全准确。 PageBase 类使用一个名为 IsSamePage 的辅助方法来确定是否应触发该事件。 默认情况下,如果请求映射到相同的物理路径并具有相同的查询字符串,则此方法返回 true。 在大多数情况下,这已经足够了,但在必要时可以重写和自定义该方法。

有趣的是,IsSamePage 的默认实现实际上并没有区分页面的单独实例。 也就是说,如果同时处理对同一页面的多个请求,您最终可能会代表页面的另一个实例处理该事件。 只要您的站点地图结构完全基于从查询字符串中获取的信息,这都无关紧要。 这是因为不同的查询字符串将导致 IsSamePage 返回 false,因此,该事件不会触发。

如果您的 SiteMapResolve 处理依赖于其他一些信息,请务必相应地覆盖 IsSamePage。 例如,如果您依赖于会话信息来构造站点地图结构,您可以像这样覆盖 IsSamePage

protected virtual bool IsSamePage(HttpContext context1, HttpContext context2)
{
    if (base.IsSamePage(context1, context2))
    {
        return context1.Session["myKey"] == context2.Session["myKey"];
    }
    
    return false;
}

使用此覆盖后,只有在以下情况下才会触发 PageBase.SiteMapResolve 事件

  • 该请求用于与当前页面相同的物理文件。
  • 该请求具有与当前页面相同的查询字符串。
  • 会话中键为 "myKey" 的会话值在两个会话中都匹配。

摘要

本文中提供的代码将使您能够更轻松地在 ASP.NET 2.0 页面中构造动态站点地图结构。 随意将 PageBase 代码复制到您自己的项目中,并在必要时对其进行修改。 您的项目中可能已经有一个基页,在这种情况下,您可以简单地将相关代码复制到您的基页中。

历史

  • 2006 年 3 月 1 日:首次修订。
© . All rights reserved.