Exportar (0) Imprimir
Expandir todo
Expandir Minimizar

Tutorial 3: Páginas principales y navegación de sitios

Junio de 2006

Publicado: 25 de Septiembre de 2006

Scott Mitchell

Descargar el código de ejemplo ASPNET_Data_Tutorial_3_CS.exe.

En esta página

Introducción Introducción
Paso 1: Creación de la página principal Paso 1: Creación de la página principal
Paso 2: Adición de una página de inicio al sitio web Paso 2: Adición de una página de inicio al sitio web
Paso 2: Creación de un mapa del sitio Paso 2: Creación de un mapa del sitio
Paso 3: Visualización de un menú según el mapa del sitio Paso 3: Visualización de un menú según el mapa del sitio
Paso 4: Adición de elementos de navegación tipo breadcrumb Paso 4: Adición de elementos de navegación tipo breadcrumb
Paso 5: Adición de la página predeterminada de cada sección Paso 5: Adición de la página predeterminada de cada sección
Resumen Resumen
Acerca del autor Acerca del autor

Introducción

Una característica común de los sitios web orientados al usuario es la presencia de un diseño de página lógico para todo el sitio y de un esquema de navegación. ASP.NET 2.0 presenta dos características nuevas que facilitan notablemente la creación de un diseño de página de todo el sitio y de un esquema de navegación: páginas principales y navegación de sitios. Las páginas principales permiten a los desarrolladores crear una plantilla para todo el sitio con regiones configuradas para la edición. Esta plantilla se puede aplicar posteriormente a las páginas ASP.NET del sitio. En dichas páginas sólo es necesario proporcionar el contenido de las regiones que se pueden editar de las páginas principales; las demás marcas de la página principal son idénticas para el resto de páginas ASP.NET que usan dicha página. Este modelo permite a los desarrolladores definir y unificar un diseño de página de todo el sitio, de modo que facilita la creación de un aspecto coherente y garantiza que todas las páginas se pueden actualizar de una forma sencilla.

El sistema de navegación de sitios ofrece a los desarrolladores de páginas un mecanismo para definir un mapa del sitio y una API para dicho mapa que se debe consultar mediante programación. Los nuevos controles web de navegación (Menu, TreeView y SiteMapPath) facilitan la transformación total o parcial del mapa del sitio en un elemento de navegación de la interfaz de usuario común. Vamos a usar el proveedor de navegación de sitios predeterminado, lo que significa que nuestro mapa del sitio estará definido en un archivo con formato XML.

Para ilustrar estos conceptos y conseguir que nuestros sitios web de tutoriales se utilicen más, durante esta lección vamos a definir un diseño de página para todo el sitio, implementar un mapa del sitio y agregar la interfaz de usuario de navegación. Cuando terminemos este tutorial habremos aprendido un diseño de sitio web perfeccionado para construir las páginas web del tutorial.

Figura 1. Resultado final del tutorial

Paso 1: Creación de la página principal

El primer paso consiste en la creación de la página principal del sitio. En estos momentos este sitio web está formado únicamente por DataSet con tipo (Northwind.xsd en la carpeta App_Code), clases BLL (ProductsBLL.cs, CategoriesBLL.cs, etc. en la carpeta App_Code), la base de datos (NORTHWND.MDF en la carpeta App_Data), el archivo de configuración (Web.config) y el archivo de la hoja de estilo CSS (Styles.css). Vacié las páginas y archivos que mostraban el uso de DAL y BLL en los dos primeros tutoriales porque analizaremos esos ejemplos con más detalle en próximos tutoriales.

Figura 2. Archivos del proyecto

Para crear una página principal, haga clic con el botón secundario en el nombre del proyecto en el Explorador de soluciones y seleccione Agregar nuevo elemento. A continuación, seleccione el tipo de página principal de la lista de plantillas y denomínela Site.master.

Figura 3. Adición de una página principal nueva al sitio web

Aquí se define el diseño de página para todo el sitio, en la página principal. Puede usar la vista Diseño y agregar todos los controles web o de diseño que necesite, o bien puede agregar las marcas manualmente en la vista Código fuente. En mi página principal uso hojas de estilo en cascada para definir las posiciones y estilos con configuración CSS definidos en el archivo externo Style.css. Mientras que no es posible deducirlo del marcado mostrado a continuación, las reglas CSS se definen de tal forma que el contenido de navegación de <div> se presente en posicionamiento absoluto para que aparezca a la izquierda y tenga una profundidad fija de 200 píxeles.

Site.master

<%@ Master Language="C#" AutoEventWireup="true" 
CodeFile="Site.master.cs" Inherits="Site" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Working with Data Tutorials</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div id="wrapper">

        <form id="form1" runat="server">
        
            <div id="header">
                <span class="title">Working with Data Tutorials</span>

                <span class="breadcrumb">TODO: Breadcrumb will go here...</span>
            </div>
        
            <div id="content">
                <asp:contentplaceholder id="MainContent" runat="server">
                  <!-- Page-specific content will go here... -->
                </asp:contentplaceholder>
            </div>
            
            <div id="navigation">
                TODO: Menu will go here...
            </div>
        </form>
    </div>
</body>
</html>

Una página principal define el diseño de página estática y las regiones que se pueden editar mediante las páginas ASP.NET que usan la página principal. El control ContentPlaceHolder, que se puede ver dentro del contenido de <div>, marca estas regiones con contenido que se puede editar. Esta página principal tiene sólo un ContentPlaceHolder (MainContent), pero las páginas principales pueden tener varios ContentPlaceHolders.

Al cambiar a la vista Diseño con el marcado anterior, se visualiza el diseño de la página principal. Todas las páginas ASP.NET que usan esta página principal tendrán este diseño uniforme y la posibilidad de especificar el marcado para la región MainContent

Figura 4. Página principal en la vista Diseño

Paso 2: Adición de una página de inicio al sitio web

Una vez que hemos definido la página principal, estamos listos para agregar páginas ASP.NET al sitio web. Empecemos por agregar Default.aspx a la página de inicio del sitio web. Haga clic con el botón secundario en el nombre del proyecto en el Explorador de soluciones y seleccione Agregar nuevo elemento. Elija la opción Formulario web de la lista de plantillas y denomine el archivo Default.aspx. También debe activar la casilla de verificación "Seleccionar la página principal".

Figura 5. Adición de formulario web nuevo, activación de la casilla de verificación "Seleccionar la página principal"

Después de hacer clic en el botón Aceptar, se nos pide que seleccionemos la página principal que debe usar esta página ASP.NET nueva. Es posible tener varias páginas principales en un proyecto, aunque ahora tengamos sólo una.

Figura 6. Selección de la página principal que debe usar la página ASP.NET

Después de elegir la página principal, las páginas ASP.NET nuevas presentarán el marcado siguiente:

Default.aspx

<%@ Page Language="C#" MasterPageFile="~/Site.master" 
AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" 
Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" 
Runat="Server">
</asp:Content>

En la directiva @Page se hace referencia al archivo de la página principal usado (MasterPageFile="~/Site.master") y el marcado de las páginas ASP.NET contiene un control Content para todos los controles ContentPlaceHolder definidos en la página principal, con los ContentPlaceHolderID del control asignados al control Content para un ContentPlaceHolder específico. El control Content es donde se coloca la marca que quiere que aparezca en el ContentPlaceHolder correspondiente. Establezca el atributo Title de la directiva @Page en Inicio y escriba algún contenido de bienvenida en el control Content:

Default.aspx

<%@ Page Language="C#" MasterPageFile="~/Site.master" 
AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" 
Title="Home" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" 
Runat="Server">

    <h1>Welcome to the Working with Data Tutorial Site</h1>

    <p>This site is being built as part of a set of tutorials that illustrate some of the 
new data access and databinding features in ASP.NET 2.0 and Visual Web 
Developer.</p>

    <p>Over time, it will include a host of samples that demonstrate:</p>
    
    <ul>
        <li>Building a DAL (data access layer),</li>
        <li>Using strongly typed TableAdapters and DataTables</li>
        <li>Master-Detail reports</li>
        <li>Filtering</li>
        <li>Paging,</li>
        <li>Two-way databinding,</li>
        <li>Editing,</li>
        <li>Deleting,</li>
        <li>Inserting,</li>
        <li>Hierarchical data browsing,</li>
        <li>Hierarchical drill-down,</li>
        <li>Optimistic concurrency,</li>
        <li>And more!</li>
    </ul>
</asp:Content>

El atributo Title de la directiva @Page nos permite indicar el título de la página desde la página ASP.NET, aunque el elemento <title> no esté definido en la página principal. También podemos definir el título mediante programación utilizando Page.Title. Observe también que las referencias de páginas principales a hojas de estilo (como Style.css) se actualizan automáticamente para que funcionen en todas las páginas ASP.NET, independientemente del directorio de la página principal donde se ubica la página ASP.NET.

Si cambiamos a la vista Diseño, podemos visualizar cómo se vería nuestra página en un explorador. Tenga en cuenta que en la vista Diseño de la página ASP.NET sólo se puede editar el contenido de las regiones configuradas para ello; la marca non-ContentPlaceHolder definida en la página principal aparece en gris.

Figura 7. La vista Diseño de la página ASP.NET muestra las regiones que se pueden y no se pueden editar

Cuando un explorador visita una página Default.aspx, el motor ASP.NET combina automáticamente el contenido de página de la página principal y el contenido de ASP.NET y representa el contenido combinado en el formato HTML final que se envía al explorador solicitante. Cuando se actualiza el contenido de la página principal, todas las páginas ASP.NET que usan esta página principal vuelven a combinar su contenido con el contenido nuevo de la página principal la próxima vez que se produzca una solicitud. En resumen, el modelo de página principal permite definir una única plantilla de diseño de página (página principal) cuyos cambios se reflejarán de forma inmediata en todo el sitio.

Adición de páginas ASP.NET adicionales al sitio web

Vamos a dedicar unos segundos a agregar códigos auxiliares de páginas ASP.NET al sitio que contendrá finalmente las diferentes demostraciones de informes. Existirán más de 35 demostraciones en total, de modo que es preferible crear sólo las primeras páginas con códigos auxiliares y no todas. Puesto que también habrá muchas categorías de demostraciones, agregue una carpeta para las categorías con el fin de administrarlas mejor. De momento, agregue las tres carpetas siguientes:

  • BasicReporting

  • Filtering

  • CustomFormatting

Por último, agregue archivos nuevos como se muestra en el Explorador de soluciones de la figura 8. Acuérdese de activar la casilla de verificación "Seleccionar la página principal" después de agregar cada archivo.

Figura 8. Adición de los archivos siguientes

Paso 2: Creación de un mapa del sitio

Una de las mayores dificultades de administrar un sitio web formado por más de unas cuantas páginas es poder ofrecer a los visitantes una forma directa de navegar por el sitio. Debemos empezar por comprobar que la estructura de navegación del sitio está definida. A continuación, dicha estructura debe estar traducida a elementos de navegación de la interfaz de usuario, como menús o elementos tipo breadcrumb. Por último, todo este proceso se debe mantener y actualizar mediante la adición de página nuevas al sitio y la eliminación de otras existentes. Antes de la creación de ASP.NET 2.0, los desarrolladores se encontraban solos ante la creación de la estructura de navegación de un sitio, su mantenimiento y la traducción de la misma a elementos de navegación de la interfaz de usuario. Sin embargo, gracias a ASP.NET 2.0 los desarrolladores pueden utilizar el sistema de navegación de sitios integrado, que ofrece una gran flexibilidad.

El sistema de navegación de sitios de ASP.NET 2.0 ofrece a los desarrolladores un medio para definir un mapa del sitio y posteriormente tener acceso a esta información a través de una API de programación. ASP.NET incluye un proveedor de mapas del sitio que asume que los datos del mapa se almacenarán en un archivo XML formateado de una forma concreta. Sin embargo, puesto que el sistema de navegación de sitios viene integrado en el modelo de proveedor, se puede ampliar para que sea compatible con otras formas de serialización de la información del mapa del sitio. El artículo de Jeff Prosise, The SQL Site Map Provider You've Been Waiting For (puede estar en inglés) explica como crear un proveedor del mapa del sitio que almacene el mapa en una base de datos de SQL Server; otra opción es crear un proveedor del mapa del sitio a partir de la estructura del sistema de archivos.

No obstante, en este tutorial vamos a usar el proveedor de mapas del sitio predeterminado que se incluye con ASP.NET 2.0. Para crear el mapa del sitio, haga clic con el botón secundario en el nombre del proyecto en el Explorador de soluciones y seleccione Agregar nuevo elemento. Mantenga el nombre Web.sitemap y haga clic en el botón Agregar

Figura 9. Adición de un mapa del sitio al proyecto

El archivo del mapa del sitio está en formato XML. Tenga en cuenta que Visual Studio incluye IntelliSense para la estructura del mapa del sitio. El archivo del mapa del sitio debe tener el nodo <siteMap> como nodo raíz, que debe contener exactamente un elemento secundario <siteMapNode>. Ese primer elemento <siteMapNode> puede, a su vez, contener un número indeterminado de elementos <siteMapNode> descendientes.

Defina el mapa del sitio en función de la estructura del sistema de archivos. Es decir, agregue un elemento <siteMapNode> para cada una de las tres carpetas y elementos secundarios <siteMapNode> para cada una de las páginas ASP.NET contenidas en dichas carpetas, como se muestra a continuación:

Web.sitemap:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

  <siteMapNode url="~/Default.aspx" title="Home" description="Home">
      <siteMapNode title="Basic Reporting" url="~/BasicReporting/Default.aspx" 
description="Basic Reporting Samples">
        <siteMapNode url="~/BasicReporting/SimpleDisplay.aspx" title="Simple 
Display" description="Displays the complete contents of a database table." />
        <siteMapNode url="~/BasicReporting/DeclarativeParams.aspx" 
title="Declarative Parameters"  description="Displays a subset of the contents of a 
database table using parameters." />
        <siteMapNode url="~/BasicReporting/ProgrammaticParams.aspx" 
title="Setting Parameter Values" description="Shows how to set parameter values 
programmatically." />
      </siteMapNode>
        
      <siteMapNode title="Filtering Reports" url="~/Filtering/Default.aspx" 
description="Samples of Reports that Support Filtering">
        <siteMapNode url="~/Filtering/FilterByDropDownList.aspx" title="Filter by 
Drop-Down List" description="Filter results using a drop-down list." />
        <siteMapNode url="~/Filtering/MasterDetailsDetails.aspx" title="Master-
Details-Details" description="Filter results two levels down." />
        <siteMapNode url="~/Filtering/DetailsBySelecting.aspx" title="Details of 
Selected Row" description="Show detail results for a selected item in a GridView." />
      </siteMapNode>

      <siteMapNode title="Customized Formatting" 
url="~/CustomFormatting/Default.aspx" description="Samples of Reports Whose 
Formats are Customized">
        <siteMapNode url="~/CustomFormatting/CustomColors.aspx" title="Format 
Colors" description="Format the grid&apos;s colors based on the underlying data." 
/>
        <siteMapNode url="~/CustomFormatting/GridViewTemplateField.aspx" 
title="Custom Content in a GridView" description="Shows using the TemplateField 
to customize the contents of a field in a GridView." />
        <siteMapNode url="~/CustomFormatting/DetailsViewTemplateField.aspx" 
title="Custom Content in a DetailsView"  description="Shows using the 
TemplateField to customize the contents of a field in a DetailsView." />
        <siteMapNode url="~/CustomFormatting/FormView.aspx" title="Custom 
Content in a FormView"  description="Illustrates using a FormView for a highly 
customized view." />
        <siteMapNode url="~/CustomFormatting/SummaryDataInFooter.aspx" 
title="Summary Data in Footer" description="Display summary data in the grid's 
footer." />        
      </siteMapNode>

  </siteMapNode>

</siteMap>

El mapa del sitio define la estructura de navegación del sitio web; se trata de una jerarquía que describe las secciones que forman el sitio. Cada elemento <siteMapNode> de Web.sitemap representa una sección de la estructura de navegación del sitio.

Figura 10. El mapa del sitio representa una estructura de navegación jerárquica (haga clic aquí para ampliarla)

ASP.NET expone la estructura del mapa del sitio a través de la clase SiteMap class!href(http://msdn2.microsoft.com/en-us/library/system.web.sitemap.aspx) de .NET Framework. Esta clase presenta una propiedad CurrentNode, que devuelve información de la sección que el usuario está visitando; la propiedad RootNode devuelve la raíz del mapa del sitio (Inicio en nuestro mapa del sitio). Ambas propiedades, CurrentNode y RootNode, devuelven instancias SiteMapNode!href(http://msdn2.microsoft.com/en-us/library/system.web.sitemapnode.aspx), que tienen propiedades como ParentNode, ChildNodes, NextSibling, PreviousSibling, etc., que permiten desplazarse por la jerarquía del mapa del sitio.

Paso 3: Visualización de un menú según el mapa del sitio

Se puede tener acceso a los datos en ASP.NET 2.0 mediante lenguaje de programación, como en ASP.NET 1.x, o bien mediante declaración a través de los controles de origen de datos nuevos. Existen varios controles de origen de datos integrados, como el control SqlDataSource para tener acceso a los datos de la base de datos relacional o el control ObjectDataSource para tener acceso a los datos de clases, entre otros. Incluso puede crear controles de origen de datos personalizados.

Los controles de origen de datos desempeñan la función de proxy entre su página ASP.NET y los datos subyacentes. Por lo general, para visualizar un conjunto de datos recuperados del control de origen de datos, se agrega otro control web a la página y se enlaza al control de origen de datos. Para enlazar un control web a un control de origen de datos, configure la propiedad DataSourceID del control web con el mismo valor de la propiedad ID del control de origen de datos.

ASP.NET incluye el control SiteMapDataSource, que nos permite enlazar un control web al mapa de nuestro sitio web, para facilitar la administración de los datos del mapa del sitio. Se usan normalmente dos controles web (TreeView y Menu) para presentar una interfaz de usuario de navegación. Para enlazar los datos del mapa del sitio a uno de estos controles, agregue un SiteMapDataSource a la página y un control TreeView o Menu que tenga la propiedad DataSourceID configurada correspondientemente. Por ejemplo, podríamos agregar un control Menu a la página principal mediante las marcas siguientes:

<div id="navigation">
    <asp:Menu ID="Menu1" runat="server" DataSourceID="SiteMapDataSource1">
    </asp:Menu>
    
    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
</div>

Para tener un mayor control sobre la página con formato HTML emitida, podemos enlazar el control SiteMapDataSource al control Repeater como sigue:

<div id="navigation">
    <ul>
        <li><asp:HyperLink runat="server" ID="lnkHome" 
NavigateUrl="~/Default.aspx">Home</asp:HyperLink></li>
        
        <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1">
            <ItemTemplate>
                <li>
                    <asp:HyperLink runat="server" NavigateUrl='<%# Eval("Url") %>'><%# 
Eval("Title") %></asp:HyperLink>
                </li>
            </ItemTemplate>
        </asp:Repeater>
    </ul>
    
    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" 
ShowStartingNode="false" />
</div>

El control SiteMapDataSource devuelve un nivel a la jerarquía del mapa del sitio cada vez; en primer lugar del nodo raíz del mapa (Inicio en nuestro mapa del sitio), a continuación de los niveles siguientes (Basic Reporting, Filtering Reports y Customized Formatting) y así sucesivamente. Cuando se enlaza SiteMapDataSource a un Repeater (repetidor), éste enumera el primer nivel devuelto y crea una instancia de ItemTemplate para cada instancia SiteMapNode del primer nivel. Para tener acceso a una propiedad concreta del SiteMapNode, podemos usar Eval(propertyName), que es la forma que tenemos de obtener las propiedades Url y Title de SiteMapNode para el control HyperLink.

El ejemplo de Repeater anterior representa el marcado siguiente:

<li>
    <a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a>
</li>

<li>
    <a href="/Code/Filtering/Default.aspx">Filtering Reports</a>
</li>

<li>
    <a href="/Code/CustomFormatting/Default.aspx">Customized Formatting</a>
</li>

Estos nodos del mapa del sitio (Basic Reporting, Filtering Reports y Customized Formatting) forman el segundo nivel representado del mapa del sitio, no el primero. La razón es que la propiedad ShowStartingNode de SiteMapDataSource está establecida en False, lo que provoca que el SiteMapDataSource omita el nodo raíz del mapa y, en vez del primer nivel, devuelve el segundo nivel de la jerarquía del mapa.

Para visualizar los elementos secundarios de Basic Reporting, Filtering Reports y Customized Formatting SiteMapNodes, podemos agregar otro Repeater al ItemTemplate del Repeater inicial. Este segundo Repeater se enlaza a la propiedad ChildNodes de la instancia SiteMapNode como sigue:

<asp:Repeater runat="server" ID="menu" 
DataSourceID="SiteMapDataSource1">
    <ItemTemplate>
        <li>
            <asp:HyperLink runat="server" NavigateUrl='<%# Eval("Url") %>'><%# 
Eval("Title") %></asp:HyperLink>

            <asp:Repeater runat="server" DataSource='<%# ((SiteMapNode) 
Container.DataItem).ChildNodes %>'>
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>
                
                <ItemTemplate>
                    <li>
                        <asp:HyperLink runat="server" NavigateUrl='<%# Eval("Url") 
%>'><%# Eval("Title") %></asp:HyperLink>
                    </li>
                </ItemTemplate>
                
                <FooterTemplate>
                    </ul>
                </FooterTemplate>
            </asp:Repeater>
        </li>
    </ItemTemplate>
</asp:Repeater>

Estos dos Repeater generan el siguiente marcado (algunas marcas se han omitido por razones de brevedad):

<li> <a href="/Code/BasicReporting/Default.aspx">Basic Reporting</a> <ul> <li> <a href="/Code/BasicReporting/SimpleDisplay.aspx">Simple Display</a> </li> <li> <a href="/Code/BasicReporting/DeclarativeParams.aspx">Declarative Parameters</a> </li> <li> <a href="/Code/BasicReporting/ProgrammaticParams.aspx">Setting Parameter Values</a> </li> </ul></li><li> <a href="/Code/Filtering/Default.aspx">Filtering Reports</a> ...</li><li> <a href="/Code/CustomFormatting/Default.aspx">Customized Formatting</a> ...</li>

Mediante los estilos CSS elegidos del libro de Rachel Andrew The CSS Anthology: 101 Essential Tips, Tricks, and Hacks (puede estar en inglés), se ha dado un estilo a los elementos <ul> y <li> cuyo marcado genera el aspecto siguiente:

Figura 11. Menú formado por dos Repeater y varios estilos CSS

Este menú se encuentra en la página principal y está enlazado al mapa del sitio definido en Web.sitemap, lo que significa que cualquier cambio realizado en el mapa del sitio se reflejará inmediatamente en todas las páginas que usen la página principal Site.master.

Deshabilitación de ViewState

Todos los controles ASP.NET pueden mantener opcionalmente su estado en el estado de vista, que se serializa como un campo de formulario oculto de la página HTML representada. Los controles se valen del estado de vista para tener presente su estado cambiado mediante programación en las devoluciones, como los datos enlazados a un control web de datos. El estado de vista permite recordar la información durante las devoluciones; sin embargo, aumenta el tamaño del marcado que se debe enviar al cliente y puede producir una recarga importante de la página si no se controla bien. Los controles web de datos, en especial el control GridView, son particularmente adecuados para agregar cantidades adicionales de kilobytes al marcado de una página. Mientras que dicho incremento puede ser insignificante con respecto al ancho de banda o a los usuarios de la intranet, el estado de vista puede sumar varios segundos al viaje de ida y vuelta de los usuarios que llaman.

Para ver el efecto del estado de vista, visite una página en un explorador y vea después el código fuente emitido por la página (en Internet Explorer, vaya al menú Ver y seleccione la opción Código fuente). También puede activar el seguimiento de página para ver la asignación del estado de vista utilizado por los controles de la página. La información del estado de vista se serializa en un campo de formulario oculto denominado __VIEWSTATE, que se ubica en un elemento <div> justo después de la etiqueta de apertura <form>. El estado de vista sólo se mantiene cuando se utiliza un formulario web; si la página ASP.NET no incluye un <form runat="server"> en la sintaxis de declaración, no existirá un campo de formulario oculto __VIEWSTATE en las marcas representadas.

El campo de formulario VIEWSTATE generado por la página principal suma alrededor de 1.800 bytes al marcado de la página. Esta recarga adicional se debe, en primer lugar, al control Repeater, porque el contenido del control SiteMapDataSource se mantiene en el estado de vista. Mientras que puede parecer que 1.800 bytes no es tanto, al usar un GridView con muchos campos y registros, el estado de vista se puede multiplicar fácilmente por 10 o más.

El estado de vista se puede deshabilitar en la misma página o mediante los controles estableciendo la propiedad EnableViewState en false, lo que reduce el tamaño del marcado representado. Puesto que el estado de vista para un control web de datos mantiene los datos enlazados a dicho control durante las devoluciones, al deshabilitar este estado para el control, se deben enlazar los datos para cada una de las devoluciones. Mientras que de esto se encarga el desarrollador de la página en la versión 1.x de ASP.NET; en ASP.NET 2.0, los controles web de datos se deben volver a enlazar al control de origen de datos para cada devolución, si es necesario.

Si desea reducir el estado de vista de la página, establezca la propiedad EnableViewState del control Repeater en false. Esto se puede realizar mediante la ventana Propiedades del Diseñador o mediante declaración en la vista Código fuente. Una vez que se ha realizado el cambio de Repeater mediante declaración, el marcado debe tener el siguiente aspecto:

<asp:Repeater runat="server" ID="menu" 
DataSourceID="SiteMapDataSource1" EnableViewState="False">
    <ItemTemplate>
        ... ItemTemplate contents omitted for brevity ...
    </ItemTemplate>
</asp:Repeater>

Después de este cambio, el tamaño del estado de vista de la página representada se habrá reducido a tan sólo 52 bytes, lo que supone un ahorro del 97% en el tamaño del estado de vista. En los tutoriales de esta serie, deshabilitaremos de forma predeterminada el estado de vista de los controles web de datos para reducir el tamaño del marcado representado. En la mayoría de los ejemplos, estableceremos la propiedad EnableViewState en false sin necesidad de explicitarlo. Sólo hablaremos del estado de vista cuando se deba habilitar para que el control web de datos cumpla su función.

Paso 4: Adición de elementos de navegación tipo breadcrumb

Para completar la página principal vamos a agregar un elemento de navegación de la interfaz de usuario tipo breadcrumb a cada página. El elemento breadcrumb muestra rápidamente a los usuarios su ubicación actual en la jerarquía del sitio. Agregar elementos breadcrumb en ASP.NET 2.0 es sencillo; sólo hay que añadir un control SiteMapPath a la página, sin necesidad de códigos.

En nuestro sitio vamos a agregar este control al <div> de encabezado:

<span class="breadcrumb">
    <asp:SiteMapPath ID="SiteMapPath1" runat="server">
    </asp:SiteMapPath>
</span>

El elemento breadcrumb muestra la página actual de la jerarquía del mapa del sitio en la que está el visitante y las páginas anteriores del nodo del mapa hasta llegar a la raíz (Inicio en nuestro mapa del sitio).

Figura 12. El elemento breadcrumb muestra la página actual y las anteriores de la jerarquía del mapa del sitio

Paso 5: Adición de la página predeterminada de cada sección

Los tutoriales de nuestro sitio están divididos en varias categorías, a saber, Basic Reporting, Filtering, Custom Formatting, etc., con una carpeta en cada una y los tutoriales correspondientes en forma de páginas ASP.NET dentro de dicha carpeta. Asimismo, cada carpeta contiene una página Default.aspx. Vamos a visualizar todos los tutoriales de esta sección correspondientes a esta página predeterminada. Es decir, tendríamos vínculos a SimpleDisplay.aspx, DeclarativeParams.aspx y ProgrammaticParams.aspx para la página Default.aspx predeterminada de la carpeta BasicReporting. Ahora podemos volver a usar la clase SiteMap y un control web de datos para ver esta información, que se corresponde con el mapa del sitio definido en Web.sitemap.

Vamos a ver una lista desordenada volviendo a usar un Repeater, pero esta vez veremos el título y la descripción de los tutoriales. Puesto que las marcas y los códigos necesarios para ello se deben repetir para cada página Default.aspx, podemos concretar esta lógica de la interfaz de usuario en un control de usuario. Cree una carpeta denominada UserControls en el sitio web y agréguele un elemento nuevo del tipo Control de usuario web denominado SectionLevelTutorialListing.ascx; agregue también el marcado que se incluye a continuación:

Figura 13. Adición de un control de usuario web a la carpeta UserControls

SectionLevelTutorialListing.ascx

<%@ Control Language="C#" AutoEventWireup="true" 
CodeFile="SectionLevelTutorialListing.ascx.cs" 
Inherits="UserControls_SectionLevelTutorialListing" %>
<asp:Repeater ID="TutorialList" runat="server" EnableViewState="False">
    <HeaderTemplate><ul></HeaderTemplate>
    <ItemTemplate>
        <li><asp:HyperLink runat="server" NavigateUrl='<%# Eval("Url") %>' 
Text='<%# Eval("Title") %>'></asp:HyperLink>
                - <%# Eval("Description") %></li>
    </ItemTemplate>
    <FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

SectionLevelTutorialListing.ascx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class UserControls_SectionLevelTutorialListing : 
System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // If SiteMap.CurrentNode is not null, 
        // bind CurrentNode's ChildNodes to the GridView
        if (SiteMap.CurrentNode != null)
        {
            TutorialList.DataSource = SiteMap.CurrentNode.ChildNodes;
            TutorialList.DataBind();
        }
    }
}

En el ejemplo de Repeater anterior, enlazamos los datos de SiteMap a Repeater mediante declaración; sin embargo, el control de usuario SectionLevelTutorialListing lo hace mediante programación. En el controlador de eventos Page_Load, se hace una comprobación para asegurarse de que esta es la primera visita a la página (no una devolución) y de que la URL de esta página está asignada a un nodo del mapa del sitio. Si dicho control de usuario se usa en una página que no se corresponde a una entrada <siteMapNode>, SiteMap.CurrentNode devolverá null y no se enlazarán datos al Repeater. Si damos por hecho que tenemos un CurrentNode, debemos enlazar la colección ChildNodes a Repeater. Puesto que nuestro mapa del sitio está configurado de tal forma que la página Default.aspx de cada sección es el nodo primario de todos los tutoriales de dicha sección, este código mostrará vínculos a todos los tutoriales de la sección junto con las descripciones correspondientes, como se muestra en la captura de pantalla siguiente.

Una vez que se ha creado este Repeater, abra las páginas Default.aspx de cada carpeta, vaya a la vista Diseño y arrastre el control de usuario en la superficie de diseño desde el Explorador de soluciones hasta el lugar donde desea que aparezca la lista de tutoriales.

Figura 14. Control de usuario agregado a Default.aspx

Figura 15. Enumeración de los tutoriales contenidos en Basic Reporting

Resumen

Con el mapa del sitio definido y la página principal completa, hemos conseguido una página con un diseño y un esquema de navegación lógicos para los tutoriales relacionados con datos. Independientemente del número de páginas que agreguemos al sitio, el proceso de actualización del diseño de página de todo el sitio o de la información de navegación es rápido y sencillo gracias a la centralización de la información. En concreto, la información de diseño de página se define en la página principal Site.master y el mapa del sitio en Web.sitemap. No necesitamos escribir ningún código para obtener este diseño de página para todo el sitio y este mecanismo de navegación y, además, hemos conseguido en Visual Studio un diseño intuitivo donde vemos lo que hay.

Después de haber terminado las capas de acceso a datos y de lógica de negocios y de haber definido un diseño de página coherente y un mecanismo de navegación del sitio, estamos preparados para empezar con los modelos de informe más comunes. En los tres tutoriales siguientes analizaremos las tareas de elaboración de informes básicas, es decir, la visualización de datos recuperados de BLL en los controles GridView, DetailsView y FormView.

Suerte con la programación.

Otras lecturas

Para obtener más información sobre los temas expuestos en este tutorial, consulte las fuentes siguientes:

Acerca del autor

Scott Mitchell, autor de seis libros sobre ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha trabajado con las tecnologías web de Microsoft desde 1998. Scott trabaja como consultor, profesor y escritor independiente y ha terminado recientemente su último libro: Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Puede ponerse en contacto con él en mitchell@4guysfromrolla.com o mediante su blog, que se encuentra en http://scottonwriting.net/.

Agradecimientos especiales a...

El elevado número de revisores de esta serie de tutoriales fue de gran utilidad. Los revisores principales de este tutorial fueron Liz Shulok, Dennis Patterson y Hilton Giesenow. Si está interesado en leer los próximos artículos que escriba para MSDN, coméntemelo a través de mitchell@4GuysFromRolla.com.

Mostrar:
© 2014 Microsoft