1

我有一个类似于此处描述的问题:
ASP.NET URL Routing with WebForms - Using the SiteMap

我的 ASP.Net WebForms web 应用程序有一个站点地图,类似于:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
  <siteMapNode title="Root">
    <siteMapNode url="Home" title="Home" />
      <siteMapNode url="Home?" title="Home" />
      <siteMapNode url="Faq" title="FAQ" />
    </siteMapNode>
    <siteMapNode url="Reports" title="Your reports" />
      <siteMapNode url="Reports?" title="Your reports" />
      <siteMapNode url="ExtraReports" title="Extra reports" />
    </siteMapNode>
    <siteMapNode url="Presentations" title="Your presentations" />
      <siteMapNode url="Presentations?" title="Your presentations" />
      <siteMapNode url="ExtraPresentations" title="Extra presentations" />
    </siteMapNode>
 </siteMapNode>

我希望网址采用以下格式::
//host/projects/{company}/{projectno}/Home
://host/projects/microsoft/10/Home
://host/projects/microsoft/ 11/报告
://host/projects/apple/10/ExtraReports

Url 路由将 /projects/{company}/{projectno}/{pagename} 路由到 /Pages/{pagename}.aspx。

我的导航由顶部的 TabStrip 组成,其中应包含Home、Reports 和 Presentations,左侧的菜单及其子项(例如,选择 Home 时应该是:Home、Faq)。

我的问题:

  1. 处理重复的 SiteMapNode url 的正确方法是什么?

  2. 如何防止 TabStrip 生成如下网址:://host/Home 和 ://host/ExtraReports?
    我需要维护当前的公司和项目没有选择,并且站点地图忽略了相对 url

  3. TabStrip 和 Menu 控件需要识别所选项目以显示活动选择。所有这一切的正确解决方案是什么?

4

2 回答 2

2

在花了几个小时之后,我想我已经找到了一个好的(足够的:))解决方案。

SiteMap文件
注意没有url的节点会指向父节点

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
    <siteMapNode>
        <siteMapNode title="Home" url="Home">
            <siteMapNode title="Home" />
            <siteMapNode title="xxx" url="Cycle"/>
            <siteMapNode title="yyy" url="Survey" />
            <siteMapNode title="zzzteam" url="Team" />
        </siteMapNode>
        ...

生成 Url
CurrentContext 的实用程序类是对 RequestContext 的静态引用

public static string GetPageUrl(SiteMapNode node) {
   RouteValueDictionary values = new RouteValueDictionary(CurrentContext.RouteData.DataTokens);
   values["page"] = node.Url.Trim('/');

   return CurrentContext.RouteData.Route.GetVirtualPath(CurrentContext, values).VirtualPath;
}

MasterPage
导航中的数据绑定事件是 Telerik Tabstrip,子导航是 ASP.Net 菜单

private void navigation_TabDataBound(object sender, Telerik.Web.UI.RadTabStripEventArgs e) {
   if (!String.IsNullOrEmpty(e.Tab.NavigateUrl)) {              
          SiteMapNode node = (SiteMapNode) e.Tab.DataItem;

   // Is this tab a parent of the current navigation node? Then select it
   if (SiteMap.CurrentNode.IsDescendantOf(node)) e.Tab.Selected = true;
          e.Tab.NavigateUrl = XRouteHandler.GetPageUrl(node);
   }
}

private void subNavigation_MenuItemDataBound(object sender, MenuEventArgs e) {
    SiteMapNode itemNode = (SiteMapNode) e.Item.DataItem;
    SiteMapNode currentNode = SiteMap.CurrentNode;

    // SiteMapNodes without url will point to the parent node
    if (String.IsNullOrEmpty(itemNode.Url)) {
        itemNode = itemNode.ParentNode;
        e.Item.Selectable = true;
    }

    // Is this menu item the node itself or one of it's parents? Then select it
    if (currentNode == itemNode || currentNode.IsDescendantOf(itemNode))
        e.Item.Selected = true;
        e.Item.NavigateUrl = XRouteHandler.GetPageUrl(itemNode);
    }
}

XmlSiteMapProvider implementation
这个解决方案现在已经足够好了,稍后会研究它来美化它:)

public override SiteMapNode FindSiteMapNode(HttpContext context) {
        string pageName = context.Request.Url.Segments.Last().Trim('/');
        foreach (SiteMapNode node in SiteMap.RootNode.GetAllNodes())
                if (node.Url.EndsWith(pageName, StringComparison.InvariantCultureIgnoreCase)) return node;
        return SiteMap.RootNode;
}
于 2010-02-02T14:36:20.023 回答
1

Zyphax,

很可能您将不得不重新编写 TabStrip 和 Menu 控件以考虑您的路线。这也意味着您可以删除重复的 SiteMapNode。

相反,您需要编写一些代码来遍历 SiteMap 树以获取最远的祖先,即主页的子项。这是一种可能会有所帮助的扩展方法。

public SiteMapNode FurthestAncestor(this SiteMapNode node)
{
    while (node.Key !=  this.RootNode.Key && node.ParentNode.Key != this.RootNode.Key)
    {
        node = node.ParentNode;
    }

    return node;
}

也使用相对 URL 将有助于../Presentations而不是/projects/apple/10/Presentations

于 2010-02-01T21:30:40.993 回答