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
- En el mismo web.sitemap, asignar aun sitemapNode un archivo fisico separado
- 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:
- SiteMapDataSource.StartingNodeUrl (Propiedad)
Obtiene o establece un nodo del mapa del sitio que el origen de datos utiliza a continuación como punto de referencia para recuperar nodos de un mapa jerárquico del sitio.
http://msdn2.microsoft.com/es-es/library/system.web.ui.webcontrols.sitemapdatasource.startingnodeurl(VS.80).aspx - SiteMapDataSource.Provider (Propiedad)
Obtiene o establece un objeto SiteMapProvider que está asociado al control de origen de datos.
http://msdn2.microsoft.com/es-es/library/system.web.ui.webcontrols.sitemapdatasource.provider(VS.80).aspx - Elemento siteMap (Esquema de configuración de ASP.NET)
Define opciones de configuración para admitir la infraestructura de configuración, almacenamiento y representación de la exploración de sitios.
http://msdn2.microsoft.com/es-es/library/1e333zt4(VS.80).aspx - SiteMap (Clase)
La clase SiteMap es una representación en memoria de la estructura de exploración de un sitio, proporcionada por uno o varios proveedores del mapa del sitio. Esta clase no se puede heredar.
http://msdn2.microsoft.com/es-es/library/system.web.sitemap(VS.80).aspx - Cómo: Configurar varios mapas de sitio y proveedores de mapas de sitio
http://msdn2.microsoft.com/es-es/library/ms178426(vs.80).aspx
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.
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
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».