SiteMap и URL-маршрутизация - PullRequest
       37

SiteMap и URL-маршрутизация

1 голос
/ 30 января 2010

У меня есть вопрос, аналогичный описанному здесь:
ASP.NET URL Routing с WebForms - Использование SiteMap

Мое веб-приложение ASP.Net WebForms имеет Sitemap, похожее на это:

<?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>

Я бы хотел, чтобы URL был в следующем формате:
: // хост / проекты / {компания} / {projectno} / Home
: // хост / проекты / Microsoft / 10 / Главная
: // хост / проекты / Microsoft / 11 / Отчеты
: // хост / проекты / яблоко / 10 / ExtraReports

Маршрутизация URL-адресов / проекты / {компания} / {имя_проекта} / {имя_папки} до /Pages/ndompagename enj.aspx.

Моя навигация состоит из вкладки TabStrip в верхней части, которая должна содержать Главная, Отчеты и презентации и Меню слева с их подэлементами (например, если выбрано Главная, это должно быть: Home, Faq ).

Мои вопросы:

  1. Как правильно обрабатывать дубликаты URL SiteMapNode?

  2. Как запретить TabStrip генерировать URL-адреса, такие как:: // host / Home и: // host / ExtraReports?
    Мне нужно сохранить текущую компанию и выбор проекта, а карта сайта игнорирует относительные URL

  3. Элементы управления TabStrip и Menu должны распознавать выбранные элементы, чтобы показать активный выбор. Каково правильное решение всего этого?

Ответы [ 2 ]

2 голосов
/ 02 февраля 2010

Потратив несколько часов на это, я думаю, что нашел хорошее (достаточно :)) решение.

Файл 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, субнавигатор - это меню 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;
}
1 голос
/ 02 февраля 2010

Zyphax,

Скорее всего, вам придется переписать элементы управления TabStrip и Menu, чтобы учесть ваши маршруты. Это также означает, что вы можете удалить дубликаты SiteMapNodes.

Вместо этого вам нужно написать некоторый код для обхода дерева 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

...