伪造SiteMap.CurrentNode以使用另一个现有的SiteMapNode

时间:2011-12-20 16:20:20

标签: c# asp.net asp.net-3.5 sitemap sitemapprovider

我的网站从数据库和xml数据动态创建站点地图。但是,对于列出新闻文章的网站的一部分,它决定不将新闻文章详细信息页放在站点地图中,这样做很有用。因此,如果您要点击新闻文章的标题(来自站点地图中的列表页面),它将带您进入包含该文章的页面,但该页面/网址不在站点地图中。

我在使用

的母版页中有控件和逻辑
SiteMap.CurrentNode

基本上,在页面加载时,我想将SiteMap.CurrentNode更改为新闻文章列表页面的节点(位于站点地图中)。因此,基本上所有在此页面上运行的逻辑都会将页面视为列表页面。无论如何我都找不到这样做。

这段代码将为我提供我想要的节点,因为我知道它的密钥。

SiteMapDataSource siteMapDataSource1 = new SiteMapDataSource();
    siteMapDataSource1.SiteMapProvider = "Main";
    SiteMapNode newsListingPageNode = siteMapDataSource1.Provider.FindSiteMapNodeFromKey(siteMapKey);

基本上我希望我能做到这一点:

SiteMap.CurrentNode = newsListingPageNode;

但无法设置CurrentNode。

有关如何做到这一点的任何建议?我很感激帮助。

2 个答案:

答案 0 :(得分:2)

根据this article,您可以为SiteMapResolve事件创建自定义处理程序,并且可能您可以从中返回自定义节点。

答案 1 :(得分:0)

这是我提出的解决方案,虽然它有点太复杂,不符合我的喜好。请记住,问题是当前查看的页面不在站点地图中,导航,控件和其他逻辑期望使用站点地图提供程序。由于页面不在站点地图中,因此站点地图提供程序不可用,因此我必须手动设置站点地图和当前节点。我们选择不在站点地图中添加新闻页面,因为它会显着增加站点地图的整体大小。

首先,我使用动态站点地图提供程序的自定义ThisNode属性而不是SiteMap.CurrentNode属性。

     public static SiteMapNode ThisNode
    {
        get
        {
            if (_thisNode == null)
            {
                if (SiteMap.CurrentNode != null)
                {
                    return SiteMap.CurrentNode;
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return _thisNode;
            }
        }
        set
        {
            _thisNode = value;
        }
    }

在新闻详情页面(/news-and-events-detail.aspx)上,我调用在动态提供程序中创建的实用程序方法。

    // Set the ThisNode property to the /news-and-events-list.aspx node.
    // This will allow all sitemap driven controls and logic (such as navs, info bar, and dynamic links) to function since these detail pages are not in the sitemap.
    DynamicSiteMapProviders.SetThisNodeToAlternateNode("/news-and-events-list.aspx");

这是实用方法:

    /// <summary>
    /// Sets the DynamicSiteMapProviders.ThisNode property to the node of specified URL.
    /// </summary>
    /// <param name="urlOfNodeToSetTo">The URL of the node to set from.</param>
    public static void SetThisNodeToAlternateNode(string urlOfNodeToSetTo)
    {
        SiteMapDataSource siteMapDataSource = new SiteMapDataSource();
        siteMapDataSource.SiteMapProvider = "Main";
        DynamicSiteMapProviders.ThisNode = siteMapDataSource.Provider.FindSiteMapNode(urlOfNodeToSetTo);
    }

现在在基本母版页中,我必须重置DynamicSiteMapProviders.ThisNode属性,因为它的静态,我不希望我访问的下一页仍然使用手动设置节点。我通过利用页面生命周期的OnUnload()事件完成运行逻辑和渲染的页面时执行此操作。查看上面的ThisNode属性的Get / Set逻辑。

// This ensures that DynamicSiteMapProviders.ThisNode is not set to the node of a previously viewed page.
// This is mainly for news and events pages that are not in the sitemap and are using the news and events listing page node as the current node.
protected override void OnUnload(EventArgs e)
{
    DynamicSiteMapProviders.ThisNode = null;
    base.OnUnload(e);
}