Pergunta

Eu tenho uma pergunta semelhante à descrita aqui:
O roteamento de URL do ASP.NET com WebForms - usando o Sitemap

Minha aplicação da web webforms do ASP.NET tem um mapa de sitem

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

Eu gostaria de ter o URL no seguinte formato:
: // host/Projects/{Company}/{ProjectNo}/Home
: // host/Projects/Microsoft/10/Home
: // host/Projects/Microsoft/11/Relatórios
: // host/Projects/Apple/10/Extrareports

As rotas de roteamento/projetos/{Company}/{ProjectNo}/{Pagename} para/}/{}/{Pagename} para /pages/ {pagename }.aspx.

Minha navegação consiste em uma tabstrip no topo que deve conter Casa, relatórios e apresentações e um menu à esquerda com seus subitems (por exemplo, com a casa selecionada, deve ser: Home, FAQ).

Minhas perguntas:

  1. Qual é a maneira correta de lidar com os URLs duplicados de sitemapnode?

  2. Como evito que a tabstrip gera URLs como:: // host/home e: // host/extrareports?
    Preciso manter a empresa atual e a seleção do projeto, e o sitemap ignora URLs relativos

  3. Os controles de tabstrip e menu precisam reconhecer os itens selecionados para mostrar a seleção ativa. Qual é a solução adequada para tudo isso?

Foi útil?

Solução

Depois de passar algumas horas nisso, acho que cheguei a uma solução boa (o suficiente :)).

Arquivo sitemap
Observe os nós sem URL apontarão para o pai

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

Classe de utilidade para gerar o URL
CurrentContext é uma referência estática ao 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;
}

Eventos de banco de dados na página principal
A navegação é uma TabStrip Telerik, a subnavigação é o menu 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);
    }
}

Implementação XMLSItemApprovider
Esta solução é boa o suficiente por enquanto, vai analisá -la mais tarde para prettificá -la :)

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

Outras dicas

Zyphax,

É mais provável que você precise reescrever os controles do TabStrip e do menu para levar em conta suas rotas. Isso também significaria que você poderia remover os sitemapnodes duplicados.

Em vez disso, você precisaria escrever algum código para atravessar a árvore do sitemap para obter o ancestral mais distante, que é um filho da página inicial. Este é um método de extensão que pode ajudar.

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

    return node;
}

Também usar URLs relativos ajudará ../Presentations ao invés de /Projetos/Apple/10/Apresentações

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top