Removendo Nós de uma SiteMapNodeCollection no ASP.NET

Gerenciar a navegação da sua aplicação ASP.NET é crucial para proporcionar uma experiência de usuário ideal. No entanto, pode haver ocasiões em que você deseja excluir certas páginas de aparecer na navegação do seu site, como um formulário de registro. Se você estiver usando um Repeater para listar nós filhos de um SiteMap, pode se perguntar como remover efetivamente nós específicos sem enfrentar problemas como o NotSupportedException, que indica que a coleção é somente leitura. Este blog o guiará por uma solução para esse problema.

Entendendo o Problema

No ASP.NET, a SiteMapNodeCollection é frequentemente utilizada para representar a estrutura das páginas do seu site. Essa estrutura pode ser especialmente útil ao vincular dados a um controle como um Repeater. No entanto, se você deseja ocultar páginas específicas, como um formulário de registro, da sua lista de navegação, simplesmente tentar Remove-los da coleção pode levar a erros, já que a SiteMapNodeCollection é somente leitura.

Aqui está uma visão geral rápida do cenário:

Situação Exemplo:

  • Tipo de Controle: Repeater
  • Fonte de Dados: SiteMapNodeCollection do web.sitemap
  • Objetivo: Excluir a página de registro (/Registration.aspx) da lista de páginas exibidas.

O Desafio

Usar o método Remove() em uma SiteMapNodeCollection leva ao seguinte erro:

NotSupportedException: “Coleção é somente leitura”.

A Solução

Para excluir efetivamente nós específicos, você realmente não precisa modificar a SiteMapNodeCollection original. Em vez disso, você pode consultar a coleção e criar um novo enumerável que contenha apenas os nós que você deseja exibir. Aqui está como fazer isso usando o LINQ.

Abordagem Passo a Passo

  1. Consultar os Nós Filhos: Use LINQ para filtrar os nós indesejados da coleção ChildNodes.
  2. Selecionar os Nós Desejados: Crie uma nova coleção que exclua a página de registro.
  3. Vincular a Nova Coleção: Defina a DataSource do seu Repeater para a nova coleção.

Implementação do Código de Exemplo

Aqui está o código recomendado em VB.NET para alcançar o resultado desejado:

Dim children = From n In SiteMap.CurrentNode.ChildNodes.Cast(Of SiteMapNode)()
               Where n.Url <> "/Registration.aspx"
               Select n

RepeaterSubordinatePages.DataSource = children
RepeaterSubordinatePages.DataBind() ' Lembre-se de vincular o Repeater

Análise do Código:

  • Consulta: O código utiliza uma consulta LINQ para filtrar os nós onde a URL é igual a /Registration.aspx.
  • Casting: Cast(Of SiteMapNode)() é crítico, pois permite que o LINQ reconheça a coleção como um conjunto de objetos SiteMapNode.
  • Vinculação: Após a filtragem, a coleção resultante children é então definida como a DataSource para o Repeater, e DataBind() é chamado para atualizar o controle.

Conclusão

Ao utilizar LINQ para filtrar nós específicos da SiteMapNodeCollection, você pode evitar os percalços de tentar modificar uma coleção somente leitura. Essa abordagem não apenas mantém seu código limpo e eficiente, mas também assegura que sua navegação exiba apenas as páginas que você considerar necessárias.

Não se esqueça, manter uma estrutura de navegação clara e concisa é um componente integral da experiência do usuário em seu site. Boas codificações!