【问题标题】:SiteMap and Url routing站点地图和 URL 路由
【发布时间】:2010-01-29 22:16:28
【问题描述】:

我有一个类似于此处描述的问题:
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/Reports
://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?
    我需要维护当前的公司和项目选择,以及站点地图会忽略相对网址

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

【问题讨论】:

    标签: asp.net webforms navigation url-routing sitemapprovider


    【解决方案1】:

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

    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 实现
    这个解决方案现在已经足够好了,稍后会研究它以美化它:)

    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;
    }
    

    【讨论】:

      【解决方案2】:

      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

      【讨论】:

      • 我今天一直在办公室工作。我想我找到了一个不错的解决方案,它确实与 TabStrip 和 Menu 控件有关。我明天会发布它。谢谢。
      猜你喜欢
      • 2017-09-08
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多