Tutorial de ASP.NET
Vista Previa de ASP.NET 2.0

Utilizando el API de Navegación de Sitio

El API de Navegación del Sitio es una entidad abstracta de programación para los datos de navegación que accedan a datos de navegación usando proveedores configurables. Un proveedor de navegación de sitio separa los detalles de almacenamiento de los datos de navegación del resto de la API. La API de Navegación del Sitio muestra los datos de navegación a través de las clases SiteMap y SiteMapNode. La clase SiteMap regresa una instancia SiteMapNode que corresponde a la página actual. También proporciona acceso al proveedor(es) que ha sido configurado para la característica de Navegación del Sitio. Un SiteMapProvider tiene una API rica para realizar las siguientes tareas:

  • Devolver instancias SiteMapNode basadas en el contexto actual del HttpContext actual, o basado en un URL arbitrario. 
  • Devolver el nodo padre o los nodos hijos de un SiteMapNode.
  • Acceder el SiteMapNode de la página actual, así como también el SiteMapNode para toda la jerarquía de navegación.  
  • Forzar las reglas de autorización para que sólo los nodos visibles para el usuario sean devueltos por el proveedor.  

Una instancia SiteMapNode expone funcionalidad e información de navegación básicas, incluyendo: 

  • Las propiedades URL, título, y descripción están disponibles también así como cualquier atributo personalizado que el desarrollador haya añadido al SiteMapNode
  • Obtener el padre de un nodo así como también sus nodos hijos
  • Navegar a través de los nodos hermanos antes y después de un nodo
  • Obtener una referencia a la instancia SiteMapProvider la cual devuelve un nodo

ASP.NET viene con un proveedor llamado XmlSiteMapProvider. Este proveedor consume datos de un archivo XML (web.sitemap) y devuelve instancias SiteMapNode basadas en sus datos. El XmlSiteMapProvider también tiene la siguiente funcionalidad: 

  • Múltiples archivos sitemap que pueden ser vinculados juntos para formar un conjunto "virtual" sencillo de datos de navegación
  • Múltiples instancias XmlSiteMapProvider pueden ser vinculadas juntas para formar un set “virtual” sencillo de datos de navegación
  • El proveedor puede opcionalmente filtrar los nodos devueltos basandose en las reglas de autorización del archivo y la autorización del URL que actualmente se aplican al sitio web

Cuando tenemos una referencia al SiteMapProvider, podemos buscar los datos de navegación de sitios para un nodo específico basado en el URL. Esto nos permite obtener referencias a las instancias SiteMapNode en cualquier lugar en nuestros datos de navegación del sitio. La combinación de encontrar arbitrariamente instancias SiteMapNode y la habilidad de navegar a través de los datos de navegación de sitios de cualquier SiteMapNode nos permite fácilmente moverte a través de los datos de navegación de tu sitio. 

Como desarrolladores, podemos escoger guardar los datos de navegación en otros almacenes de datos utilizando otros formatos (por ejemplo – como datos relacionales en una base de datos). Podemos entonces crear un proveedor personalizado que se derive de SiteMapProvider.

Creando un Mapa de Aplicación del Sitio

Las estructuras de navegación para los ejemplos del Inicio Rápido de la Navegación de Sitios son representados en archivos Web.sitemap. En el archivo sitemap que podemos ver abajo, se muestra toda la estructura para el Tutorial de Inicio Rápido. Un archivo Web.sitemap contiene en el nivel más alto un sólo elemento <siteMap>. Anidado dentro del elemento <siteMap> encontramos, al menos, un elemento <siteMapNode>. Siempre debe de haber un <siteMapNode> en el nivel superior dentro del mapa del sitio. La característica de Navegación de Sitios requiere un solo elemento raíz <siteMapNode> para asegurar la convergencia a un único y conocido nodo al movernos por la jerarquía de nodos. Podemos anidar tantos elementos  <siteMapNode> bajo el elemento raíz  <siteMapNode> como sean necesarios. Adicionalmente, podemos anidar elementos <siteMapNode> a cualquier profundidad arbitraria.

Un elemento individual <siteMapNode> normalmente contiene los atributos Url, Title y Description. El atributo Url puede indicar el path virtual que corresponde a una página en nuestra aplicación. También pueden contener paths a páginas en otras aplicaciones, o URLs que apunten a sitios web completamente diferentes. En el ejemplo de abajo, todos los atributos Url usan sintaxis relativa a la aplicación para hacer referencia a paths localizados dentro de la aplicación QuickStart. El atributo Title es usado para mostrar texto cuando se muestra la UI para los datos de navegación. Por ejemplo, el control SiteMapPath usa el atributo Title para mostrar el texto de los hipervínculos del control. Si el atributo Description se encuentra presente, los controles de servidor pueden usar esta información para mostrar tooltips o texto altenativo. Un desarrollador pueden también agregar atributos personalizados a un <siteMapNode> y todos estos atributos estarán disponibles usando el indexador por defecto en la clase SiteMapNode. Para información en otros atributos soportados en el elemento <siteMapNode> por favor vea a la documentación del Framework de .NET. 

Ejemplo Web.sitemap

Programando con las Clases de Navegación de Sitios

Podemos obtener datos de la navegación del sitio programáticamente en código. El punto de inicio para obtener los datos de la Navegación del Sitio programáticamente es la clase SiteMap. Hay una variedad de métodos estáticos en esta clase, de los cuales es más importante es la propiedad CurrentNode. En cualquier página de nuestro sitio web podemos llamar a SiteMap.CurrentNode para referenciar la parte de los datos de navegación que concuerde con la página que actualmente se esta ejecutando. Los datos de Navegación son devueltos como una instancia de un SiteMapNode - cuando llamamos a SiteMap.CurrentNode la propiedad devuelve una instancia SiteMapNode correspondiente a la página actual. La característica de Navegación de Sitio determina el nodo correcto a devolver basandose en datos de navegación que son almacenados en un archivo XML.

El siguiente ejemplo demuestra un control de usuario con paginación simple. En la página que se muestra, el control de usuario se sitúa en el centro inferior de la página. Inicialmente existe un link [Next Topic]. Cuando se da clic sobre este link, el control de usuario llama al objeto SiteMap para determinar si existen páginas hermanas a la actual. Desde la propiedad SiteMap.CurrentNodeel código determina si hay páginas hermanas previas (SiteMap.CurrentNode.PreviousSibling) así como determina si hay páginas hermanas a continuación (SiteMap.CurrentNode.NextSibling). Basado en la existencia de páginas hermanas, el control de usuario muestra hipervínculos, fijando la propiedad NavigateUrl de cada hipervínculo al valor de la propiedad Url del nodo hermano.

Si hacemos clic en varios vínculos del TreeView en el lado izquierdo de la página, también podremos observar que el control de usuario automáticamente despliega los vínculos [Next Topic] y [Previous Topic] apropiados. El control de usuario también muestra un hipervínculo en el cual podemos hacer clic para regresar a la página de inicio. Si observamos el código y ves como este hipervínculo se muestra, el control usa un atributo personalizado del elemento <siteMapNode> de la página de inicio llamado "customAttribute". El control muestra como usar el indexador por defecto de SiteMapNode para devolver el valor de este atributo personalizado.

C# SiteMap API


Seguridad en la Navegación de Sitio

La característica de Navegación de Sitios puede, opcionalmente, filtrar las instancias SiteMapNode devueltas por un proveedor basados en reglas de autorización. El XmlSiteMapProvider puede filtrar nodos basandose en el archivo y las reglas de autorización de URL que se apliquen al sitio web actual.

El siguiente ejemplo usa autenticación basada en formularios con credenciales de usuario predefinidas guardadas en el archivo web.config. En global.asax, los roles se adjuntan a la petición actual basandose en el nombre de usuario. En el archivo web.config, el elemento  <add> anidado dentro del elemento <siteMap> tiene el valor de su atributo securityTrimmingEnabled attribute fijado a true. El archivo web.config también define un número de reglas de autorización de URLs al final del archivo. Cuando ejecutamos el ejemplo y nos autenticamos, el XmlSiteMapProvider automáticamente realizará una comprobación de la autorización para cada SiteMapNode, basada en la combinación de roles a los que el usuario pertenece y en las reglas de autorización definidas en el archivo web.config.

Prueba a ejecutar el ejemplo con una de las siguientes cuentas de usuario:

  • Userid: SectionOne    Password: SectionOne
  • Userid: SectionTwo    Password: SectionTwo
  • Userid: AllSections     Password: AllSections

Hay un enlace de cierre de sesión en la esquina superior derecha de la página para que podamos iniciar o cerrar sesión con cuentas diferentes. Observad como dependiendo de cual sea la cuenta que utilicemos para autenticarnos, la interfaz de navegación desplegada en los controles TreeView y Menu automáticamente cambia para reflejar las URLs a los que cada usuario está autorizado a acceder. El proveedor automáticamente filtra y devuelve los nodos - no se require de código extra para este comportamiento. Autenticarse como un usuario "SectionOne" hace que sólo se muestren vínculos para "SectionOne" y vínculos externos en el control TreeView de la parte izquierda.  Autenticarse como un usuario "SectionTwo" hace que se muestren vínculos para "SectionTwo" y vínculos externos en el control TreeView de la parte izquierda. Autenticarse como un usuario "AllSections" despliega todos los vínculos en el control TreeView. Las reglas de autorización en el archivo web.config son configuradas para otorgar acceso de forma selectiva a las jerarquías de los URLs de "SectionOne" y "SectionTwo" 

Este ejemplo tambien muestra como funciona la seguridad con URLs que se encuentran fuera del alcance del directorio de una aplicación. En el archivo web.sitemap el atributo roles es usado en los nodos para vínculos externos. La síntaxis roles="*" otorga a todos los usuarios el derecho de obtener y ver cada nodo en los controles de navegación. La síntaxis roles="Adminstrators,Regular Users" permite solamente a los usuarios en estos roles el derecho de obtener y ver los nodos en los controles de navegación. Debido a que el archivo global.asax asigna usuarios en este ejemplo a uno de estos dos roles, seremos siempre capaces de ver los vínculos externos.

Los desarrolladores tienen la opción de usar las reglas de autorización de archivo/URL y el atributo roles para controlar el acceso a instancias de SiteMapNode. Si ambos grupos de información se encuentran disponibles, un proveedor de navegación de sitios tratará de autorizar al usuario actual basado en ambos: en las reglas de autorización de archivo/URL y en los roles dentro del atributo roles. Si el usuario actual pasa cualquier grupo de verificación de autorización, entonces al usuario actual se le otorgará acceso al nodo.

Si el comportamiento de seguridad por defecto no es conveniente para nuestra aplicación, un desarrollador puede derivar de XmlSiteMapProvider y sobrecargar el método IsAccessibleToUser con una implementación personalizada para la autorización de los nodos.


C# Seguridad en la Navegación de Sitios

Localizando los Datos del Mapa de Sitio

Los datos de navegación son almacenados en un archivo sitemap puede necesitar localizarse. Los atributos URL, Title y Descripction en un elemento <siteMapNode> pueden ser localizados. Además, cualquier atributo personalizado que un programador coloque en un elemento <siteMapNode>

El ejemplo incluye texto para los lenguajes Inglés y Francés. El archivo web.sitemap usa dos tipos de expresiones de localización para lograr esto: Expresiones implícitas y expresiones explícitas. Para más detalles de Expresiones de Localización en general, así como información a fondo de los dos tipos de expresiones de localización visita el tema “Localizando tu Aplicación” en el Tutorial de Inicio Rápido. Un archivo sitemap indica que usa datos de localización por la existencia de enableLocalization=true en la raíz del elemento sitemap

En un archivo sitemap las expresiones implícitas hacen más fácil para un desarrollador el etiquetar cada elemento <siteMapNode> con una llave de búsqueda que será usada para retornar recursos desde un archivo de recursos. En el ejemplo web.sitemap, las expresiones de recursos implícitas están en cada nodo excepto en el primero. La sintaxis luce como sigue: resourceKey="Autos". Cuando el XmlSiteMapProvider obtiene un SiteMapNode basado en la información dentro del archivo web.sitemap, buscará una cadena de recursos basada en la combinación del nombre de la propiedad SiteMapNode, la resourceKey y el valor del atributo siteMapFile configurado por el proveedor. Usando el nodo “Autos” como ejemplo, el proveedor buscará un archivo de recursos que empiece con “web.sitemap” basado en la cultura actual. Esto significa que si el navegador envía el encabezado con el lenguaje francés, entonces el proveedor buscará por un archivo de recursos llamado web.sitemap.fr.resx.  En el archivo de recursos, el proveedor buscará una llave de recursos cuyo nombre se base en resourceKey + "." + [nombre de la propiedad SiteMapNode]. Usando la propiedad Title para el nodo “Autos” como ejejmplo, el proveedor buscará un recurso en el cual la llave es Autos.Title dentro del archivo de recursos llamado web.sitemap.fr.resx

Las expresiones explícitas otorgan al programador mayor control sobre los archivos que contienen recursos de localización así como el nombre de la llave de recurso. En el ejemplo web.sitemap, un recurso de expression explícita es utilizado por el primer elemento  <siteMapNode>. Las Expresiones explícitas son específicadas en una base por-atributo. El primer elemento <siteMapNode> usa una expression explícita para el atributo Title. Una expresión explícita siempre debe iniciar con  $resource:. Después de este identificador, un desarrollador debe proveer el nombre raíz para el archivo de recursos, así como para la llave de recurso.De forma opcional, el desarrollador puede proporcionar un valor por defecto. En el ejemplo, la expresión  $resources: Title, MyTitle , Home indica al proveedor que debe buscar en un archivo de recursos que empieza por “Title”. Para un navegador que envía un encabezado en idioma francés, el proveedor buscaría por un archivo de recursos llamado Title.fr.resx. El proveedor entonces buscará por un recurso el cual su llave es MyTitle. Si el proveedor no puede encontrar tal recurso, volverá a intentarlo usando la cadena “Home” como su valor por defecto. 

Para ver los efectos de la localización de mapas de sitios, ejecutad el ejemplo. A los navegadores que indican Inglés como el lenguaje por defecto se les devolverá el texto en inglés. Si estáis usando IE, podéis cambiar el lenguaje por defecto yendo a Herramientas --> Opciones de Internet y seleccionando el botón de “Lenguajes” en la pestaña “General”. Presionad el botón “Agregar” y escoge añadir el lenguaje “Francés (Francia) [fr]” como un lenguaje. Si es necesario, seleccionad la opción para el lenguaje Francés y presionad “Mover Arriba” para hacerlo el lenguaje por defecto solicitado por IE. Después de cambiar el lenguaje default a francés, refrescad la página de muestra. Observad que el texto en los controles Menu, TreeView y SiteMapPath automáticamente cambia para reflejar el texto en francés almacenado en los archivos de recurso francés localizados en el directorio App_GlobalResources.  

C# Sitemap Localization


Modificando los Datos de Navegación de Sitio Devueltos por los Proveedores

Los datos de navegación contenidos en web.sitemap consumidos por el XmlSiteMapProvider son estáticos – los datos se cargan en memoria y se almacenan como datos de solo-lectura. Sin embargo, muchos sitios tienen una estructura de navegación que es parametrizada y está basado en valores querystring. Por ejemplo, un sitio de grupo de noticias puede tener una estructura bien definida de páginas (ejem. Una página inicial, una página de categorías de noticias, y una página con el artículo de la noticia), pero el contenido real puede variar dependiendo de identificadores del querystring. Aunque es posible guardar cualquier cambio en los valores querystring en elementos <siteMapNode>, incluso para un  número moderado de  valores querystring, un archivo sitemap puede contener cientos de miles de elementos <siteMapNode>.

La característica de Navegación de Sitios da acceso al evento SiteMapResolve de la clase base SiteMapProvider. Una suscripción al evento se puede hacer mediante SiteMap.SiteMapResolve o directamente contra proveedores individuales usando SiteMap.Provider.SiteMapResolve. El valor devuelto por el evento es una instancia SiteMapNode. En tu manejador del evento puedes escribir lógica personalizada para crear una jerarquía de las instancias SiteMapNode. Esta lógica puede modificar las propiedades en cada SiteMapNode para que así las propiedades como URL y Title reflejen información adicional basada en los datos tomados del querystring.

El siguiente ejemplo registra un manejador de eventos en in global.asax. El código para el manejador de eventos está en una clase localizada dentro del directorio App_Code. La clase personalizada hace una copia de la instancia SiteMapNode correspondiente a la página actual. Debido a que los nodos de XmlSiteMapProvider son de sólo lectura, llamando al método Clone en un SiteMapNode retorna una instancia escribible del nodo. En el ejemplo se le envía un valor de true al método  Clone, lo que resulta en una copia escribible del actual SiteMapNode así como también de todos los padres el nodo. El resto del código en la clase inspecciona la página actual y el querystring de la página actual para determinar en qué lugar de la jerarquía de sitios está ubicada la página actual. El código arregla las propiedades URL y Title incluyendo información adicional para que la interfaz de navegación mostrada por el control SiteMapPath refleje el path real que el usuario del sitio web por medio de clics ha seguido para llegar a la página actual.

Cuando ejecutamos el ejemplo inicialmente estamos en la página de inicio del sitio. El control SiteMapPath reflejará esto también. Haciendo clic en cualquier otro de los vínculos nos llevará a la página de categoría que desplegara vínculos a los artículos de noticias correspondientes a una categoría de noticias específica. Observad que si nos posicionamos sobre el ultimo vínculo del control SiteMapPath, la URL que se despliega en la barra de estado del navegador incluye información del querystring especificando el tipo de categoría de noticias. Hacer clic en uno de los vínculos posteados nos llevará a la página de noticias posteadas. Si nos posicionamos sobre uno de los vínculos del control SiteMapPath, observamos que los últimos dos vínculos del control tienen URLs y Títulos que contienen el querystring correcto e información descriptiva basada en el clickpath. Si navegamos de regreso a la página de inicio del sitio, tratad de dar clic el otro grupo de vínculos de noticias y contenidos, y de nuevo notamos como el control SiteMapPath se actualiza para reflejar el segundo grupo de vínculos en los cuales hicimos clic.

C# Utilizando el Evento SiteMapResolve