Varios SitemapProviders en la misma App Web (archivos .sitemap)

Una de las tantas preguntas frecuentes en los grupos de noticias de asp.net y tambien de algunos amigos es de como separar los items de menú principal (y más aún cuando hay elementos de secciones privadas o de administración), aqui coloco algunos tips a tener en cuenta y lo que podemos hacer. 

Filtrando los items del sitemap

En el origen de datos de sitemap tenemos la posibilidad de filtrar desde que nodo publicar los items del menu

<asp:SiteMapDataSource ID="SiteMapDataSourceMenuPrincipal"         
      runat="server"          
      StartingNodeUrl="~/admin/index.aspx" />

Esto es bueno cuando queremos que desde un subidirectorio solamente presentar en un submenu los items internos, pero…
De donde obtiene los items?

Como siempre digo la “magia” está en que hay un proveedor sitemap por defecto el cual obtiene los datos del web.sitemap, pero tenemos la posibilidad de agregar nuestros propios proveedores de mapas del sitio.
Para los que somos curiosos el proveedor por defecto se llama AspNetXmlSiteMapProvider y se encuentra en el web.config base, su ubicacion
C:WINDOWSMicrosoft.NETFrameworkv2.0.50727CONFIG

Separando los itemes (nodos) en archivos y como utilizarlos

Tenemos dos maneras de implementar en diferentes archivos el contenido de los items del sitemap

  1. En el mismo web.sitemap, asignar aun sitemapNode un archivo fisico separado
  2. Definir nuevos proveedores de sitemap en el web.config

 

OPCION 1: Para cada siteMapNone indicar en que archivo fisico se encuentran los items
Aqui podremos tener algo asi:

<siteMapNode siteMapFile="~/admin/Web.STARWARS.ADMIN.sitemap"></siteMapNode>

Donde el atributo puede ser:

  • Una referencia relativa a la aplicación, como ~/admin/Web.STARWARS.ADMIN.sitemap (teniendo en cuenta signo ~ hace referencia a la appweb)
  • Una ruta de acceso virtual, como /admin/… (como cualquier source en html)
  • Una referencia a la ruta de acceso relativa a la ubicación del archivo del mapa del sitio actual, como admin/Web.STARWARS.ADMIN.sitemap.

 

OPCION 2: Implementar nuevos proveedores de sitemap

Aqui deberiamos agregar a nuestro web.config en la seccion correcta un nuevo proveedor

<siteMap enabled="true">
    <providers>
        <add name="STARWARS.ADMIN.SiteMapProvider"
            description="Mapa del sector de Administracion"
            type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
            siteMapFile="~/admin/Web.STARWARS.ADMIN.sitemap" />
    </providers>
</siteMap>

Es una coleccion entonces podriamos tener varios

<siteMap enabled="true">
    <providers>
        <add name="STARWARS.ADMIN.SiteMapProvider" ...
        <add name="STARWARS.JEDIS.SiteMapProvider" ...
        <add name="STARWARS.SITHS.SiteMapProvider" ....

Incluso es conveniente para una mejor administración coloar un proveedor por defecto para no estar especificandolo luego en cada lugar que deseamos utilizarlo

<siteMap defaultProvider="STARWARS.JEDIS.SiteMapProvider" enabled="true">

Y mas aun si eliminamos los anteriores (el proveedor por defecto AspNetXmlSiteMapProvider), que como es una coleccion podemos hacer un clear

<siteMap defaultProvider="STARWARS.ADMIN.SiteMapProvider" enabled="true">
   <providers>
       <clear/>         
       <add...

Para utilizar tenemos la propiedad SiteMapProvider en el SiteMapDataSource

<asp:SiteMapDataSource ID="SiteMapDataSourceMenuPrincipal" 
        runat="server" 
        SiteMapProvider="STARWARS.ADMIN.SiteMapProvider"/>

 

 

Enlaces:

3 comentarios en “Varios SitemapProviders en la misma App Web (archivos .sitemap)”

  1. Hola Jose, muy interesante tu articulo, pero no he podido lograr hacerlo usando diferentes provedores, la opcion 1 me funciona perfecto solo que nose si puedo hacer que solo los usuarios a los que les corresponda un sitemap solo vean ese, sin ver los demas sitemaps, mi caso es 2 tipos de usuarios diferentes, 1 sitemap en la raiz web.sitemap, una carpeta x y una y, un sitemap x.sitemap dentro de la carpeta x y un y.sitemap en la carpeta y, ambas carpetas con su respectivo masterPage, donde cada uno despliega un menu, solo que en ambos master page, ambos usuarios en sus respectivas paginas de navegacion, se muestra su treeview pero aparecen ambos sitemap, osea que x puede navegar dentro del sitemap de y y viceversa…intente usar la opcion 2 y me da el error de “No se encontró SiteMapProvider ‘STARWARS.ADMIN.SiteMapProvider'” Detalles de la excepción: System.Web.HttpException: No se encontró SiteMapProvider ‘STARWARS.ADMIN.SiteMapProvider’.
    Seguimiento de la pila:

    [HttpException (0x80004005): No se encontró SiteMapProvider ‘STARWARS.ADMIN.SiteMapProvider’.]
    System.Web.UI.WebControls.SiteMapDataSource.get_Provider() +296
    System.Web.UI.WebControls.SiteMapDataSource.GetHierarchicalView(String viewPath) +13
    System.Web.UI.HierarchicalDataSourceControl.System.Web.UI.IHierarchicalDataSource.GetHierarchicalView(String viewPath) +7
    System.Web.UI.WebControls.HierarchicalDataBoundControl.GetData(String viewPath) +22
    System.Web.UI.WebControls.TreeView.DataBindNode(TreeNode node) +75
    System.Web.UI.WebControls.TreeView.PerformDataBinding() +313
    System.Web.UI.WebControls.HierarchicalDataBoundControl.PerformSelect() +72
    System.Web.UI.WebControls.BaseDataBoundControl.DataBind() +68
    System.Web.UI.WebControls.TreeView.DataBind() +4
    System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() +61
    System.Web.UI.WebControls.TreeView.OnPreRender(EventArgs e) +40
    System.Web.UI.Control.PreRenderRecursiveInternal() +88
    System.Web.UI.Control.PreRenderRecursiveInternal() +171
    System.Web.UI.Control.PreRenderRecursiveInternal() +171
    System.Web.UI.Control.PreRenderRecursiveInternal() +171
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5731

    Versión de Microsoft .NET Framework:2.0.50727.832; Versión ASP.NET:2.0.50727.832

    Tendras algo que me pueda ayudar a solucionar esto, te lo agradeceré, miestras seguire googleando en busca de una solución…..Gracias por el articulo.

  2. Hola Pedro
    El error que arroja es:
    No se encontró SiteMapProvider ‘STARWARS.ADMIN.SiteMapProvider’
    Cuando quiere ejecutar este metodo
    SiteMapDataSource.get_Provider()

    Has declarado en el web.config los proveedores?
    Ya que si no lo declaras no tiene forma de conocer donde se encuentra ese archivo, si puedes postear parte del codigo de como implementas mejor.
    O sea cuando utilizas

    Ira a buscar al web.config un proveedor que debe estar especificado

  3. OJO, ami tb me ha estado dando ese mismo error, cuando estava empezando a desesperarme he ido a ver el archivo web.config del Windows/Microsof.Net/Framework y me he fijado donde estava el nodo de SiteMap por defecto que era debajo de httpHandlers, asi pues cogi el nodo SiteMap de el web config de mi app y lo puse debajo del nodo httpHandlers y ahora si me funciona.
    La conclusion que he sacado es que deve de compilar el archivo en un orden pre-definido y se estava olvidando de compilarme el sitemap hasta que lo he puesto “en su sitio”.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *