Almacenador de estado de páginas de ASP.NET 2.0

Diciembre de 2005

Publicado: 27 de Marzo de 2006

Por Matt Gibbs
Jefe de desarrollo, herramientas y plataforma Web

Este artículo se aplica a:
ASP.NET 2.0
Visual Studio 2005

Resumen: ASP.NET 2.0 permite modificar el lugar de almacenamiento de datos de ViewState de las páginas. En este artículo se explica cómo crear una clase y utilizarla para almacenar información de ViewState en Sesión en lugar del campo oculto predeterminado. (5 páginas impresas.)

En esta página

Contenido Contenido
Acerca del autor Acerca del autor

Contenido

Los desarrolladores del control de ASP.NET utilizan ViewState y estado del control para almacenar información de estado entre las solicitudes del explorador. Por lo general, esta información se transporta al cliente como un campo oculto en el marcado HTML procesado por la página. Este estado de página luego se envía como parte del siguiente envío de formularios al servidor y se restaura en el control o la página. Esto permite a los desarrolladores del control ofrecer con facilidad una mejor aplicación al brindarles la posibilidad de almacenar información de estado temporalmente aunque el explorador esté utilizando el protocolo HTTP, que por definición es independiente.

ASP.NET 2.0 permite modificar dónde y cómo se almacena temporalmente el estado de la página. En algunos casos, es preferible no enviar datos entre el cliente y el servidor. Los dos almacenadores de estado de páginas incluidos en ASP.NET 2.0 son el ya mencionado HiddenFieldPageState y SessionPageStatePersister. SessionPageStatePersister utiliza sesiones de servidor asociadas con la sesión del explorador para almacenar los datos. Esto tiene ventajas y desventajas. Al utilizar Sesión en lugar de un campo oculto no se aumenta el tamaño de la página enviada al explorador y luego devuelta. En muchas situaciones, el estado de la página es parte fundamental del marcado general. Sin embargo, al almacenar estos datos en Sesión se consumen valiosos recursos del servidor. Además, a diferencia de las sesiones, los campos ocultos no poseen un tiempo de espera asociado. Se puede configurar una aplicación para que almacene sesiones en una base de datos de servidor y no haga falta poner la carga directamente sobre el servidor Web. Esto también sirve para conjuntos de servidores Web.

A fin de utilizar un almacenador diferente al predeterminado, hay que reemplazar la propiedad PageStatePersister de la página y devolver una instancia de otro almacenador. En primer lugar, aquí hay una página sencilla que llena una ArrayList con un montón de números y luego la enlaza a un control GridView.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    protected override PageStatePersister PageStatePersister {
        get {
            return new SessionPageStatePersister(this);
        }
    }
    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        if (!IsPostBack) {
            ArrayList list = new ArrayList();
            for (int i = 0; i < 1000; i++)
            {
                list.Add(Convert.ToString(i));
            }
            GridView1.DataSource = list;
            GridView1.DataBind();      
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server" />        
        <asp:Button ID="Button1" runat="server" Text="Submit" /></div>
    </form>
</body>
</html>

Al observar el código HTML procesado para la página, verá un campo oculto grande para transportar ViewState.

<!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><title>
   Untitled Page
</title></head>
<body>
    <form name="form1" method="post" action="default2.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
value="/wEPDwUKMTQ0MDQzNjk2Ng9kFgICBA9kFgICAQ88KwANAgAPFgYeC18hRGF0YUJv
dW5kZx4JUGFnZUNvdW50AgEeC18hSXRlbUNvdW50AhRkDBQrAAEWBh4EVHlwZRkrAh4ETmF
tZQUESXRlbR4JRGF0YUZpZWxkBQEhFgJmD2QWKgIBD2QWAmYPDxYCHgRUZXh0BQEwZGQCAg
9kFgJmDw8WAh8GBQExZGQCAw9kFgJmDw8WAh8GBQEyZGQCBA9kFgJmDw8WAh8GBQEzZGQCB
Q9kFgJmDw8WAh8GBQE0ZGQCBg9kFgJmDw8WAh8GBQE1ZGQCBw9kFgJmDw8WAh8GBQE2ZGQC
CA9kFgJmDw8WAh8GBQE3ZGQCCQ9kFgJmDw8WAh8GBQE4ZGQCCg9kFgJmDw8WAh8GBQE5ZGQ
CCw9kFgJmDw8WAh8GBQIxMGRkAgwPZBYCZg8PFgIfBgUCMTFkZAIND2QWAmYPDxYCHwYFAj
EyZGQCDg9kFgJmDw8WAh8GBQIxM2RkAg8PZBYCZg8PFgIfBgUCMTRkZAIQD2QWAmYPDxYCH
wYFAjE1ZGQCEQ9kFgJmDw8WAh8GBQIxNmRkAhIPZBYCZg8PFgIfBgUCMTdkZAITD2QWAmYP
DxYCHwYFAjE4ZGQCFA9kFgJmDw8WAh8GBQIxOWRkAhUPDxYCHgdWaXNpYmxlaGRkGAEFCUd
yaWRWaWV3MQ9nZMhHZ3iQZp62S8IR8fTJ5ZL42ira" />
</div>
...

Al agregar un reemplazo de la propiedad PageStatePersister y utilizar la SessionPageStatePersister incorporada, el comportamiento de la página no se modifica, pero el almacenamiento utilizado para la mayoría de los datos de estado pasa del campo oculto al campo Sesión.

    protected override PageStatePersister PageStatePersister
    {
        get
        {
            return new SessionPageStatePersister(this);
        }
    }

Observe que en el código fuente de la página el valor del campo oculto es mucho menor, pero todavía no desapareció. ASP.NET todavía transportará una cantidad mínima de datos en la salida de la página.

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
value="/wEPaA8FDzhjNzkyNTMzNjE1YWEyNxgBBQlHcmlkVmlldzEPZ2QZw
44JLJFcglwRl9TiNliE82yAuQ==" />

En algunos casos, deseará agregar un código similar en un grupo pequeño de páginas, por lo cual agregar un reemplazo simple como éste puede ser aceptable. Cuando quiera este comportamiento en toda una aplicación o un grupo más grande de páginas, deseará un método más centralizado para controlarlo. Existen muchas formas de lograrlo. Puede mover el código que crea el almacenador a la clase que hereda de la página:

using System;
using System.Data;
using System.Configuration;
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 class PagePersisterBasePage : Page
{
    public PagePersisterBasePage()   {
    }
    protected override PageStatePersister PageStatePersister {
        get {
            return new SessionPageStatePersister(this);
        }
    }
}

ASP.NET 2.0 permite especificar un tipo base para una página mediante la directiva de página "Inherits". El código generado por ASP.NET para la página entonces hereda de la página base y no hace falta duplicar el código en cada página.

<%@ Page Language="C#"  Inherits="PagePersisterBasePage" %>

Además, las opciones de configuración permiten definir una ubicación de las páginas para que todos utilicen un mismo tipo de página base. En esta página web.config, definimos pageBaseType y no precisamos agregar el atributo Inherits en ninguna página para obtener el comportamiento personalizado PageStatePersister.

<?xml version="1.0"?>
<configuration>
   <system.web>
    <pages pageBaseType="PagePersisterBasePage" />
   </system.web>
</configuration>

Modificar PageStatePersister no es algo sencillo. Hay que tener en cuenta la aplicación y la implementación. Hay sobrecarga asociada con el envío de ViewState en un campo oculto, pero hay consumo directo de recursos del servidor para conservar el estado allí. También se puede ver en el ejemplo anterior que es posible insertar un almacenador personalizado para almacenar el estado en otro lugar, como una base de datos de servidor o un servicio de estado compartido de conjuntos de servidores Web. Además, tal como se demostró, se puede controlar el comportamiento de la aplicación de forma centralizada o página por página.

Acerca del autor

Matt Gibbs es ingeniero jefe de diseño de software de ASP.NET en Microsoft, donde trabaja en tecnologías de desarrollo Web desde 1997. Fue coautor de varios libros sobre ASP y ASP.NET

Mostrar: