Páginas maestras y navegación del sitio (VB)

por Scott Mitchell

Descargar PDF

Una característica común de los sitios web fáciles de usar es que tienen un esquema de navegación y diseño de página coherente para todo el sitio. En este tutorial se examina cómo puede crear una apariencia coherente en todas las páginas que se pueda actualizar fácilmente.

Introducción

Una característica común de los sitios web fáciles de usar es que tienen un esquema de navegación y diseño de página coherente para todo el sitio. En ASP.NET 2.0 se presentan dos características nuevas que simplifican considerablemente la implementación de un diseño de página para todo el sitio y un esquema de navegación: páginas maestras y navegación del sitio. Las páginas maestras permiten a los desarrolladores crear una plantilla para todo el sitio con áreas modificables designadas. Después, esta plantilla se puede aplicar a páginas ASP.NET del sitio. Estas páginas ASP.NET solo necesitan proporcionar contenido para las áreas modificables especificadas de la página maestra, el resto del marcado de la página maestra es idéntico en todas las páginas ASP.NET en las que se usa la página maestra. Este modelo permite a los desarrolladores definir y centralizar un diseño de página para todo el sitio, lo que facilita la creación de una apariencia coherente en todas las páginas que se puede actualizar fácilmente.

El sistema de navegación del sitio proporciona un mecanismo para que los desarrolladores de páginas definan un mapa del sitio y una API para que ese mapa del sitio se consulte mediante programación. Los nuevos controles web de navegación Menu, TreeView y SiteMapPath facilitan la representación de la totalidad o parte del mapa del sitio en un elemento de interfaz de usuario de navegación común. Usará el proveedor de navegación del sitio predeterminado, lo que significa que el mapa del sitio se definirá en un archivo con formato XML.

Para ilustrar estos conceptos y hacer que el sitio web de tutoriales sea más utilizable, esta lección se centrará en la definición de un diseño de página para todo el sitio, la implementación de un mapa del sitio y la adición de la interfaz de usuario de navegación. Al final de este tutorial, tendrá un diseño de sitio web completo para crear las páginas web del tutorial.

The End Result of This Tutorial

Figura 1: Resultado final de este tutorial (Haga clic para ver la imagen a tamaño completo)

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

El primer paso es crear la página maestra del sitio. En este momento, el sitio web solo consta del objeto DataSet con tipo (Northwind.xsd, en la carpeta App_Code), las clases de la BLL (ProductsBLL.vb, CategoriesBLL.vb, etc., todas en la carpeta App_Code), la base de datos (NORTHWND.MDF, en la carpeta App_Data), el archivo de configuración (Web.config) y un archivo de hoja de estilos CSS (Styles.css). Se han limpiado esas páginas y archivos que muestran el uso de la DAL y la BLL de los dos primeros tutoriales, ya que esos ejemplos se volverán a analizar con más detalle en tutoriales posteriores.

The Files in Our Project

Figura 2: Los archivos del proyecto

Para crear una página maestra, haga clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones y elija Agregar nuevo elemento. Después, seleccione el tipo Página maestra de la lista de plantillas y asígnele el nombre Site.master.

Add a New Master Page to the Website

Figura 3: Adición de una nueva página maestra al sitio web (Haga clic para ver la imagen a tamaño completo)

Definirá el diseño de página para todo el sitio en la página maestra. Puede usar la vista Diseño y agregar cualquier diseño o controles web que necesite, o bien puede agregar manualmente el marcado en la vista Origen. En esta página maestra se usan hojas de estilo CSS para el posicionamiento y los estilos con los valores CSS definidos en el archivo Style.css externo. Aunque no se puede apreciar en el marcado que se muestra a continuación, las reglas CSS se definen de modo que el contenido del elemento <div> de navegación tiene una posición absoluta para que aparezca a la izquierda con un ancho fijo de 200 píxeles.

Site.master

<%@ Master Language="VB" AutoEventWireup="true"
    CodeFile="Site.master.vb" 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 maestra define tanto el diseño de página estático como las regiones que pueden editar las páginas ASP.NET en las que se usa la página maestra. Estas áreas modificables de contenido se indican mediante el control ContentPlaceHolder, que se puede ver dentro del elemento <div> de contenido. Las página maestra tiene un solo control ContentPlaceHolder (MainContent), pero las páginas maestras pueden tener varios.

Después de introducir el marcado anterior, al cambiar a la vista Diseño se muestra el diseño de la página maestra. Cualquier página ASP.NET que use esta página maestra tendrá este diseño uniforme, con la capacidad de especificar el marcado de la región MainContent.

The Master Page, When Viewed Through the Design View

Figura 4: La página maestra en la vista Diseño (Haga clic para ver la imagen a tamaño completo)

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

Con la página maestra definida, ya puede agregar las páginas ASP.NET del sitio web. Para empezar se agregará Default.aspx, la página principal del sitio web. Haga clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones y elija Agregar nuevo elemento. Elija la opción Formulario web de la lista de plantillas y asigne el nombre Default.aspx al archivo. Además, active la casilla "Seleccionar página maestra".

Add a New Web Form, Checking the Select master page Checkbox

Figura 5: Adición de un nuevo formulario web y selección de la casilla Seleccionar página maestra (Haga clic para ver la imagen a tamaño completo)

Después de hacer clic en el botón Aceptar, se le pedirá que elija qué página maestra debe usar esta nueva página ASP.NET. Aunque puede tener varias páginas maestras en el proyecto, aquí solo hay una.

Choose the Master Page this ASP.NET Page Should Use

Figura 6: Elección de la página maestra que debe usar esta página ASP.NET (Haga clic para ver la imagen a tamaño completo)

Después de seleccionar la página maestra, las nuevas páginas ASP.NET contendrán el marcado siguiente:

Default.aspx

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

En la directiva @Page hay una referencia al archivo de página maestra que se usa (MasterPageFile="~/Site.master") y el marcado de la página ASP.NET contiene un control Content para cada uno de los controles ContentPlaceHolder definidos en la página maestra, y el elemento ContentPlaceHolderID del control asigna el control Content a un elemento ContentPlaceHolder específico. El control Content es donde se coloca el marcado que quiere que aparezca en el elemento ContentPlaceHolder correspondiente. Establezca el atributo Title de la directiva @Page en Inicio y agregue un mensaje de bienvenida al control Contenido:

Default.aspx

<%@ Page Language="VB" MasterPageFile="~/Site.master"
    AutoEventWireup="true" CodeFile="Default.aspx.vb"
    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 permite establecer el título de la página desde la página ASP.NET, aunque el elemento <title> esté definido en la página maestra. También se puede establecer el título mediante programación con Page.Title. Observe también que las referencias de la página maestra a hojas de estilos (como Style.css) se actualizan de forma automática para que funcionen en cualquier página ASP.NET, independientemente del directorio en el que se encuentre la página ASP.NET en relación con la página maestra.

Al cambiar a la vista Diseño puede ver el aspecto que tendrá la página en un explorador. Tenga en cuenta que, en la vista Diseño de la página ASP.NET, solo se pueden editar las áreas modificable del contenido, el marcado que no es ContentPlaceHolder definido en la página maestra aparece atenuado.

The Design View for the ASP.NET Page Shows Both the Editable and Non-Editable Regions

Figura 7: La vista Diseño de la página ASP.NET muestra las áreas modificables y no modificables (Haga clic para ver la imagen a tamaño completo)

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

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

Dedique un momento a agregar códigos auxiliares de página ASP.NET adicionales al sitio que finalmente contendrán las distintas demostraciones de informes. Habrá más de 35 demostraciones en total, por lo que en lugar de crear todas las páginas de código auxiliar, solo se crearán las primeras. Como también habrá muchas categorías de demostraciones, para administrarlas mejor, agregue una carpeta para las categorías. Por ahora, agregue las tres carpetas siguientes:

  • BasicReporting
  • Filtering
  • CustomFormatting

Por último, agregue nuevos archivos como se muestra en el Explorador de soluciones de la figura 8. Al agregar cada archivo, no olvide activar la casilla "Seleccionar página maestra".

Add the Following Files

Figura 8: Adición de los archivos siguientes

Paso 2: Creación de un mapa del sitio

Uno de los desafíos de administrar un sitio web compuesto por más de una serie de páginas es proporcionar una manera sencilla para que los visitantes naveguen por el sitio. Para empezar, se debe definir la estructura de navegación del sitio. A continuación, esta estructura se debe traducir en elementos navegables de la interfaz de usuario, como menús o rutas de navegación. Por último, todo este proceso se debe mantener y actualizar a medida que se agregan nuevas páginas al sitio y se quitan las existentes. Antes de ASP.NET 2.0, los desarrolladores se encargaban de crear la estructura de navegación del sitio, mantenerla y traducirla en elementos navegables de la interfaz de usuario. Pero con ASP.NET 2.0, los desarrolladores pueden usar el sistema de navegación del sitio integrado, que es muy flexible.

El sistema de navegación del sitio de ASP.NET 2.0 proporciona un medio para que un desarrollador defina un mapa del sitio y, después, acceda a esta información desde una API mediante programación. ASP.NET incluye un proveedor de mapas del sitio que espera que los datos del mapa del sitio se almacenen en un archivo XML con un formato determinado. Pero, como que el sistema de navegación del sitio se basa en el modelo de proveedor, se puede ampliar para admitir formas alternativas de serializar la información del mapa del sitio. En el artículo de Jeff Prosise, El proveedor de mapas del sitio de SQL que esperaba se muestra cómo crear un proveedor de mapa del sitio que almacena el mapa del sitio en una base de datos de SQL Server.

Pero en este tutorial se usará el proveedor de mapa del sitio predeterminado que se incluye con ASP.NET 2.0. Para crear el mapa del sitio, simplemente haga clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones, elija Agregar nuevo elemento y elija la opción Mapa del sitio. Deje el nombre como Web.sitemap y haga clic en el botón Agregar.

Add a Site Map to Your Project

Figura 9: Adición de un mapa del sitio al proyecto (Haga clic para ver la imagen a tamaño completo)

El archivo de mapa del sitio es un archivo XML. Tenga en cuenta que Visual Studio proporciona IntelliSense para la estructura del mapa del sitio. El archivo de mapa del sitio debe tener el nodo <siteMap> como nodo raíz, que debe contener precisamente un elemento secundario <siteMapNode>. Después, ese primer elemento <siteMapNode> puede contener un número arbitrario de elementos descendientes <siteMapNode>.

Defina el mapa del sitio para imitar la estructura del sistema de archivos. Es decir, agregue un elemento <siteMapNode> para cada una de las tres carpetas y elementos <siteMapNode> secundarios para cada una de las páginas ASP.NET de esas carpetas, de la siguiente manera:

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 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 grids footer." />
      </siteMapNode>

  </siteMapNode>

</siteMap>

El mapa del sitio define la estructura de navegación del sitio web, que es una jerarquía en la que se describen las distintas secciones del sitio. Cada elemento <siteMapNode> de Web.sitemap representa una sección de la estructura de navegación del sitio.

The Site Map Represents a Hierarchical Navigational Structure

Figura 10: El mapa del sitio representa una estructura de navegación jerárquica (Haga clic para ver la imagen a tamaño completo)

ASP.NET expone la estructura del mapa del sitio mediante la clase SiteMap de .NET Framework. Esta clase tiene una propiedad CurrentNode, que devuelve información sobre la sección que el usuario visita actualmente; la propiedad RootNode devuelve la raíz del mapa del sitio (Inicio, en el ejemplo). Las propiedades CurrentNode y RootNode devuelven instancias de SiteMapNode, que tiene propiedades como ParentNode, ChildNodes, NextSibling, PreviousSibling, etc., que permiten recorrer la jerarquía del mapa del sitio.

Paso 3: Representación de un menú basado en el mapa del sitio

El acceso a los datos en ASP.NET 2.0 se puede realizar mediante programación, como en ASP.NET 1.x, o bien mediante declaración, con los nuevos controles de origen de datos. Hay varios controles de origen de datos integrados, como SqlDataSource, para acceder a datos de base de datos relacionales, el control ObjectDataSource, para acceder a datos de clases y otros. Incluso puede crear controles de origen de datos personalizados propios.

Los controles de origen de datos sirven como proxy entre la página ASP.NET y los datos subyacentes. Para mostrar los datos recuperados de un control de origen de datos, normalmente 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, simplemente establezca la propiedad DataSourceID del control web en el valor de la propiedad ID del control de origen de datos.

Para ayudar a trabajar con los datos del mapa del sitio, ASP.NET incluye el control SiteMapDataSource, que permite enlazar un control web con el mapa del sitio web. Se suelen usar dos controles web, TreeView y Menu, para proporcionar una interfaz de usuario de navegación. Para enlazar los datos del mapa del sitio a uno de estos dos controles, basta con agregar una instancia de SiteMapDataSource a la página junto con un control TreeView o Menu cuya propiedad DataSourceID se establece en consecuencia. Por ejemplo, se podría agregar un control Menu a la página maestra mediante el marcado siguiente:

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

    <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
</div>

Para tener un mayor grado de control sobre el HTML emitido, se puede enlazar el control SiteMapDataSource al control Repeater, de la siguiente manera:

<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 la jerarquía de mapa del sitio por niveles individuales, empezando por el nodo raíz del mapa del sitio (Inicio, en este ejemplo), después el siguiente nivel (Informes básicos, Informes de filtrado y Formato personalizado), etc. Al enlazar SiteMapDataSource a un control Repeater, enumera el primer nivel devuelto y crea una instancia de ItemTemplate para cada instancia de SiteMapNode de ese primer nivel. Para acceder a una propiedad determinada de SiteMapNode, puede usar Eval(propertyName), que es cómo se obtienen las propiedades Url y Title de SiteMapNode para el control HyperLink.

El ejemplo de Repeater anterior representará 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 de mapa del sitio (Informes básicos, Informes de filtrado y Formato personalizado) componen el segundo nivel del mapa del sitio que se representa, no el primero. Esto se debe a que la propiedad ShowStartingNode de SiteMapDataSource se establece en False, lo que hace que SiteMapDataSource omita el nodo de mapa del sitio raíz y, en su lugar, comience con la devolución del segundo nivel en la jerarquía de mapa del sitio.

Para mostrar los elementos secundarios de las instancias de SiteMapNode Informes básicos, Informes de filtrado y Formato personalizado, se puede agregar otro control Repeater al elemento ItemTemplate del control Repeater. Este segundo control Repeater se enlazará a la propiedad ChildNodes de la instancia SiteMapNode, de la siguiente manera:

<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="<%# CType(Container.DataItem,
             SiteMapNode).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 controles Repeater dan como resultado el marcado siguiente (se ha quitado parte del marcado por motivos 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 The CSS Anthology: 101 Essential Tips, Tricks, & Hacks (Antología de CSS: 101 sugerencias y trucos esenciales) de Rachel Andrew, se aplica estilo a los elementos <ul> y <li>, de forma que el marcado crea la siguiente salida visual:

A Menu Composed from Two Repeaters and Some CSS

Figura 11: Un menú compuesto por dos controles Repeater y CSS

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

Deshabilitación de ViewState

Todos los controles ASP.NET pueden conservar opcionalmente su estado en el estado de visualización, que se serializa como un campo de formulario oculto en el código HTML representado. Los controles usan el estado de visualización para recordar su estado cambiado mediante programación entre postbacks, como los datos enlazados a un control web de datos. Aunque el estado de visualización permite recordar la información entre postbacks, aumenta el tamaño del marcado que se debe enviar al cliente y puede provocar un sobredimensionamiento de página grave si no se supervisa detenidamente. Los controles web de datos, en concreto GridView, son especialmente conocidos por agregar docenas de kilobytes adicionales de marcado a una página. Aunque este aumento puede ser insignificante para los usuarios de banda ancha o intranet, el estado de visualización puede agregar varios segundos al recorrido de ida y vuelta para los usuarios de acceso telefónico.

Para ver el impacto del estado de visualización, visite una página en un explorador y, después, vea el código fuente enviado por la página web (en Internet Explorer, vaya al menú Ver y elija la opción Código fuente). También puede activar el seguimiento de páginas para ver la asignación de estado de visualización que usa cada uno de los controles de la página. La información de estado de visualización se serializa en un campo de formulario oculto denominado __VIEWSTATE, ubicado en un elemento <div> inmediatamente después de la etiqueta <form> de apertura. El estado de visualización solo se conserva cuando se usa un formulario web; Si la página ASP.NET no incluye un elemento <form runat="server"> en su sintaxis declarativa, no habrá ningún campo de formulario oculto __VIEWSTATE en el marcado representado.

El campo de formulario __VIEWSTATE generado por la página maestra agrega aproximadamente 1800 bytes al marcado generado de la página. Este sobredimensionamiento adicional se debe principalmente al control Repeater, ya que el contenido del control SiteMapDataSource se conserva en el estado de visualización. Aunque es posible que 1800 bytes adicionales no parezcan muchos, cuando se usa un control GridView con muchos campos y registros, el estado de visualización puede crecer fácilmente por un factor de 10 o superior.

El estado de visualización se puede deshabilitar en el nivel de página o control si se establece la propiedad EnableViewState en False, lo que reduce el tamaño del marcado representado. Como el estado de visualización de un control web de datos conserva los datos enlazados al control entre postbacks, al deshabilitar el estado de visualización de un control web de datos, los datos se deben enlazar en cada postback. En la versión 1.x de ASP.NET, esta responsabilidad recaía sobre el desarrollador de la página; pero con ASP.NET 2.0, los controles web de datos se volverán a enlazar a su control de origen de datos en cada postback si es necesario.

Para reducir el estado de visualización de la página, se establecerá la propiedad EnableViewState del control Repeater en False. Esto se puede hacer desde la ventana Propiedades del Diseñador, o bien mediante declaración en la vista Origen. Después de realizar este cambio, el marcado declarativo del control Repeater debe ser similar al siguiente:

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

Después de este cambio, el tamaño del estado de visualización representado de la página se ha reducido a 52 bytes, un ahorro del 97 %. En los tutoriales de esta serie, se deshabilitará el estado de visualización de los controles web de datos de forma predeterminada para reducir el tamaño del marcado representado. En la mayoría de los ejemplos, la propiedad EnableViewState se establecerá en False sin mencionarlo. Solo se mencionará el estado de visualización en escenarios en los que se deba habilitar para que el control web de datos proporcione su funcionalidad esperada.

Paso 4: Adición de rutas de navegación

Para completar la página maestra, se agregará un elemento de la interfaz de usuario de navegación de ruta de navegación a cada página. La ruta de navegación muestra rápidamente a los usuarios su posición actual dentro de la jerarquía del sitio. La adición de una ruta de navegación en ASP.NET 2.0 es fácil: simplemente agregue un control SiteMapPath a la página; no se necesita código.

Para el sitio, agregue este control al encabezado <div>:

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

La ruta de navegación muestra la página actual que el usuario visita en la jerarquía de mapa del sitio, así como en los "antepasados" del nodo del mapa del sitio, hasta la raíz (Inicio, en este ejemplo).

The Breadcrumb Displays the Current Page and its Ancestors in the Site Map Hierarchy

Figura 12: La ruta de navegación muestra la página actual y sus antecesores en la jerarquía del mapa del sitio

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

Los tutoriales del sitio se dividen en diferentes categorías: Informes básicos, Filtrado, Formato personalizado, etc., con una carpeta para cada categoría y los tutoriales correspondientes como páginas ASP.NET dentro de esa carpeta. Además, cada carpeta contiene una página Default.aspx. En esta página predeterminada, se mostrarán todos los tutoriales de la sección actual. Es decir, para Default.aspx en la carpeta BasicReporting habría vínculos a SimpleDisplay.aspx, DeclarativeParams.aspx y ProgrammaticParams.aspx. De nuevo, aquí se puede usar la clase SiteMap y un control web de datos para mostrar esta información en función del mapa del sitio definido en Web.sitemap.

Ahora se mostrará una lista sin ordenar de nuevo con un control Repeater, pero esta vez se mostrarán el título y la descripción de los tutoriales. Como el marcado y el código para lograr esto deberán repetirse para cada página Default.aspx, se puede encapsular esta lógica de interfaz de usuario en un control de usuario. Cree una carpeta en el sitio web con el nombre UserControls y agregue un nuevo elemento de tipo Control de usuario web denominado SectionLevelTutorialListing.ascxy agregue el marcado siguiente:

Add a New Web User Control to the UserControls Folder

Figura 13: Adición de un nuevo control de usuario web a la carpeta UserControls (Haga clic para ver la imagen a tamaño completo)

SectionLevelTutorialListing.ascx

<%@ Control Language="VB" AutoEventWireup="true"
    CodeFile="SectionLevelTutorialListing.ascx.vb"
    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.vb

Partial Class UserControls_SectionLevelTutorialListing 
    Inherits UserControl

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        If SiteMap.CurrentNode IsNot Nothing Then
            TutorialList.DataSource = SiteMap.CurrentNode.ChildNodes
            TutorialList.DataBind()
        End If
    End Sub
End Class

En el ejemplo de Repeater anterior se han enlazado los datos SiteMap al control Repeater mediante declaración; pero el control de usuario SectionLevelTutorialListing lo hace mediante programación. En el controlador de eventos Page_Load, se realiza una comprobación para asegurarse de que la dirección URL de esta página se asigna a un nodo del mapa del sitio. Si este control de usuario se usa en una página que no tiene una entrada <siteMapNode> correspondiente, SiteMap.CurrentNode devolverá Nothing y no se enlazará ningún dato al control Repeater. Suponiendo que hay una instancia de CurrentNode, se enlaza su colección ChildNodes al control Repeater. Como el mapa del sitio está configurado de forma que la página Default.aspx de cada sección sea el nodo primario de todos los tutoriales de esa sección, este código mostrará vínculos y descripciones de todos los tutoriales de la sección, como se muestra en la captura de pantalla siguiente.

Una vez que se cree este control Repeater, abra las páginas Default.aspx de cada una de las carpetas, vaya a la vista Diseño y simplemente arrastre el control de usuario desde la Explorador de soluciones a la superficie Diseño donde quiera que aparezca la lista de tutoriales.

The User Control has Been Added to Default.aspx

Figura 14: El control de usuario se ha agregado a Default.aspx (Haga clic para ver la imagen a tamaño completo)

The Basic Reporting Tutorials are Listed

Figura 15: Los tutoriales de Informes básicos aparecen en la lista (Haga clic para ver la imagen a tamaño completo)

Resumen

Con el mapa del sitio definido y la página maestra completada, ahora tiene un diseño de página coherente y un esquema de navegación para los tutoriales relacionados con datos. Independientemente del número de páginas que se agreguen al sitio, actualizar el diseño de página para todo el sitio o la información de navegación del sitio es un proceso rápido y sencillo debido a que esta información está centralizada. En concreto, la información de diseño de página se define en la página maestra Site.master y el mapa del sitio en Web.sitemap. No ha sido necesario escribir ningún código para lograr este mecanismo de navegación y diseño de página para todo el sitio, y se conserva la compatibilidad completa con el diseñador WYSIWYG en Visual Studio.

Después de completar la capa de acceso a datos y la capa de lógica de negocios, y de haber definido un diseño de página y una navegación del sitio coherentes, ya puede empezar a explorar patrones de creación de informes comunes. En los tres tutoriales siguientes verá tareas básicas de creación de informes que muestran los datos recuperados de la BLL en los controles GridView, DetailsView y FormView.

¡Feliz programación!

Lecturas adicionales

Para más información sobre los temas tratados en este tutorial, consulte los siguientes recursos:

Acerca del autor

Scott Mitchell, autor de siete libros de ASP y ASP.NET, y fundador de 4GuysFromRolla.com, trabaja con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, entrenador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Puede ponerse en contacto con él a través de mitchell@4GuysFromRolla.com. o de su blog, que se puede encontrar en http://ScottOnWriting.NET.

Agradecimientos especiales a

Esta serie de tutoriales fue revisada por muchos revisores. Los revisores principales de este tutorial han sido Liz Shulok, Dennis Patterson y Hilton Giesenow. ¿Le interesaría revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.