Compartir a través de


Información general sobre el estado de vista en ASP.NET

Actualización: noviembre 2007

El estado de vista es el método que utiliza el marco de la páginas ASP.NET para conservar los valores de página y control entre viajes de ida y vuelta. Cuando se representa el marcado HTML de la página, el estado actual de la página y los valores que se deben conservar durante la devolución de datos se serializan en cadenas codificadas en base64. Esta información se coloca a continuación en el campo o campos ocultos del estado de vista.

Este tema contiene:

  • Escenarios

  • Características del estado de vista

  • Información general

  • Referencia de clase

  • Recursos adicionales

  • Lo nuevo

Escenarios

El marco de la página ASP.NET usa automáticamente el estado para conservar información que se debe mantener entre las devoluciones de datos. Esta información incluye cualquier valor no predeterminado de los controles.

También puede usar el estado de vista para almacenar datos de aplicación específicos de una página.

Volver al principio de la página

Características

Un estado de vista es un repositorio de una página ASP.NET que puede almacenar valores que se deben retener durante la devolución de datos. El marco de la página usa el estado de vista para conservar los valores de control entre las devoluciones de datos.

Puede usar el estado de vista en sus propias aplicaciones para hacer lo siguiente:

  • Mantener los valores entre las devoluciones de datos sin almacenarlos en el estado de sesión o en un perfil de usuario.

  • Almacenar los valores de propiedades de control o página que define.

  • Crear un proveedor de estados de vista personalizado que permita almacenar la información de estado de vista en una base de datos de SQL Server o en otro almacén de datos.

Por ejemplo, en el estado de vista puede almacenar información a la que el código puede tener acceso durante el evento de carga de la página la próxima vez que la página se envíe al servidor. Para conocer las recomendaciones de uso, vea Recomendaciones de administración de estado de ASP.NET.

Volver al principio de la página

Información general

Una aplicación Web no tiene estado. Cada vez que el servidor solicita una página se crea una nueva instancia de la clase de página web. Normalmente esto supondría que toda la información de la página y de sus controles se perdería en cada viaje de ida y vuelta. Por ejemplo, si un usuario inserta información en un cuadro de texto de una página web HTML, dicha información se envía al servidor de forma predeterminada. Sin embargo, no se devuelve al explorador en la respuesta.

Para superar esta limitación intrínseca de la programación web, el marco de la página ASP.NET incluye varias características de administración de estados para conservar los valores de página y control entre viajes de ida y vuelta al servidor web. Uno de estas características es el estado de vistaInformación general sobre la administración de estados de ASP.NET.

De forma predeterminada, el marco de la página ASP.NET usa el estado de vista para conservar los valores de página y control entre viajes de ida y vuelta. Cuando se representa el HTML de la página, el estado actual de la página y los valores que se deben conservar durante la devolución de datos se serializan en cadenas codificadas en base64. Estas cadenas se colocan a continuación en un campo o campos ocultos de la página.

Puede tener acceso al estado de vista del código mediante la propiedad ViewState de la página. La propiedad ViewState es un diccionario que contiene pares clave/valor con los datos del estado de vista.

Nota de seguridad:

Para un usuario malintencionado es fácil ver y modificar el contenido de un campo oculto. Para obtener más información sobre cómo proteger los datos de estado de vista, vea Proteger el estado de vista más adelante en este tema.

Para obtener recomendaciones sobre cuándo debe almacenar información en estado de vista, vea Recomendaciones de administración de estado de ASP.NET.

Es posible cambiar el comportamiento predeterminado y almacenar el estado de vista en otra ubicación, como por ejemplo, en una base de datos de SQL Server implementando una clase personalizada PageStatePersister para almacenar los datos de página. Para obtener un ejemplo del almacenamiento del estado de página en una secuencia en lugar de en un campo oculto, vea el ejemplo para la clase PageStatePersister.

Consideraciones para la utilización del estado de vista

El estado de vista proporciona información de estado para una página específica ASP.NET. Si necesita usar información de más de una página o si desea que la información permanezca para todas las visitas al sitio web, debe usar otro método para mantener el estado. Puede usar el estado de aplicación, el estado de sesión o propiedades de perfil.

La información del estado de vista se serializa en XML y luego se codifican en base64, lo cual puede generar grandes cantidades de datos. Cuando se expone la página en el servidor, el contenido del estado de vista se envía como parte de la información de devolución de datos de la página. Si el estado de vista contiene una gran cantidad de información, puede afectar al rendimiento de la página. Debe probar el rendimiento de las páginas utilizando datos típicos para la aplicación y así determinar si el tamaño del estado de vista provoca problemas de rendimiento. Para obtener alternativas a la utilización del estado de vista, vea Recomendaciones de administración de estado de ASP.NET.

Si no tiene que almacenar información de control de algún control individual, puede deshabilitar el estado de vista para un control. Si un control de una página se actualiza a partir del almacén de datos en cada devolución de datos, puede desactivar el estado de vista para ese control y reducir así el tamaño del estado de vista. Por ejemplo, puede desactivar el estado de vista de un control como el control GridView.

Nota:

Incluso cuando deshabilita explícitamente el estado de vista, un campo oculto se envía al explorador para indicarle que se está produciendo una devolución de datos para la página.

Otra consideración que se debe tener en cuenta es que si la cantidad de datos de un campo oculto llega a ser muy grande, algunos servidores proxy y algunos firewalls impedirán el acceso a la página que los contiene. Debido a que la cantidad máxima permitida puede variar con distintas implementaciones de firewall y proxy, los campos ocultos de gran tamaño pueden causar problemas intermitentes. Si la cantidad de datos almacenados en la propiedad ViewState supera el valor especificado en la propiedad MaxPageStateFieldLength de la página, ésta divide el estado de vista en varios campos ocultos. De esta forma se reduce el tamaño de los campos ocultos individuales por debajo del tamaño que rechazan los firewalls.

Algunos dispositivos móviles no permiten ningún campo oculto. Por lo tanto, el estado de vista no funcionará para dichos dispositivos. Para obtener más información y alternativas, vea Información general sobre el desarrollo Web en ASP.NET Mobile.

Estado de control

Además del estado de vista, ASP.NET es compatible con el estado de control. La página utiliza el estado de control para mantener información del control que debe conservarse entre devoluciones de datos, independientemente de que el estado de vista esté deshabilitado para la página o para un control. Al igual que el estado de vista, el estado de control se almacena en uno o más campos ocultos.

Guardar valores en el estado de vista

Puede tener acceso a la información del estado de vista mediante la propiedad ViewState de la página, que expone un objeto de diccionario. Puede usar este diccionario para almacenar valores personalizados. Un uso típico consiste en almacenar el valor de propiedades personalizadas que define en la página.

Puesto que el estado de vista se envía como un campo oculto, puede realizar cambios en él hasta el evento PreRenderComplete de la página. Después de que la página se represente en el explorador, no se guardarán los cambios en el estado de vista.

Los usuarios pueden ver la información en el campo de estado de vista oculto si ven el origen de la página web y pueden descodificar cadenas codificadas en base64. Esto crea un posible problema de seguridad. Para obtener más información sobre los problemas de seguridad relacionados con el estado de vista, vea Proteger el estado de vista más adelante en este tema.

Nota:

Para usar la propiedad ViewState, la página web ASP.NET debe tener un elemento form con el atributo .

Para guardar un valor en el estado de vista, cree un nuevo elemento que contenga el valor que desea guardar y agregue el elemento al diccionario del estado de vista. En el ejemplo siguiente se muestra una página web ASP.NET con código que guarda una cadena y un valor entero en el estado de vista.

<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >
  ' Sample ArrayList for the page.
  Dim PageArrayList As ArrayList

  Function CreateArray() As ArrayList
    ' Create a sample ArrayList.
    Dim result As ArrayList
    result = New ArrayList(4)
    result.Add("item 1")
    result.Add("item 2")
    result.Add("item 3")
    result.Add("item 4")
    Return result
  End Function

  Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
    If (Me.ViewState("arrayListInViewState") IsNot Nothing) Then
      PageArrayList = CType(Me.ViewState("arrayListInViewState"), ArrayList)
    Else
      ' ArrayList isn't in view state, so it must be created and populated.
      PageArrayList = CreateArray()
    End If
    ' Code that uses PageArrayList.
  End Sub

  Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs)
    ' Save PageArrayList before the page is rendered.
    Me.ViewState.Add("arrayListInViewState", PageArrayList)
  End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>View state sample</title>
</head>
<body>
    <form id="form1" >
    <div>
    </div>
    </form>
</body>
</html>

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >
  // Sample ArrayList for the page.
  ArrayList PageArrayList;

  ArrayList CreateArray()
  {
    // Create a sample ArrayList.
    ArrayList result = new ArrayList(4);
    result.Add("item 1");
    result.Add("item 2");
    result.Add("item 3");
    result.Add("item 4");
    return result;
  }

  void Page_Load(object sender, EventArgs e)
  {
    if (ViewState["arrayListInViewState"] != null)
    {
      PageArrayList = (ArrayList)ViewState["arrayListInViewState"];
    }
    else
    {
      // ArrayList isn't in view state, so it must be created and populated.
      PageArrayList = CreateArray();
    }
    // Code that uses PageArrayList.
  }
    
  void Page_PreRender(object sender, EventArgs e)
  {
    // Save PageArrayList before the page is rendered.
    ViewState.Add("arrayListInViewState", PageArrayList);
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
    <title>View state sample</title>
</head>
<body>
    <form id="form1" >
    <div>
    </div>
    </form>
</body>
</html>

Tipos de datos que puede almacenar en estado de vista

Puede almacenar objetos de los siguientes tipos en estado de vista:

  • Cadenas

  • Enteros

  • Valores Boolean

  • Objetos Array

  • Objetos ArrayList

  • Tablas hash

  • Convertidores de tipos personalizados (vea la clase TypeConverter para obtener más información)

Asimismo, puede almacenar otros tipos de datos, pero la clase debe compilarse con el atributo Serializable para que sus valores se puedan serializar en el estado de vista.

Leer valores del estado de vista

Para leer un valor del estado de vista, obtiene la propiedad ViewState de la página y, a continuación, lee el valor del diccionario del estado de vista.

En el siguiente ejemplo se muestra cómo se puede obtener un objeto ArrayList denominado arrayListInViewState desde un estado de vista y cómo se puede enlazar posteriormente un control GridView al objeto como origen de datos.

Dim arrayList As ArrayList
arrayList = CType(ViewState("arrayListInViewState"), ArrayList)

Me.GridView1.DataSource = arrayList
Me.GridView1.DataBind()

arrayList = new ArrayList();
arrayList = (ArrayList)ViewState["arrayListInViewState"];

this.GridView1.DataSource = arrayList;
this.GridView1.DataBind();

Los valores del estado de vista son de tipo String. En Visual Basic, si establece Option Strict On, debe convertir los valores del estado de vista en el tipo adecuado antes de usarlos, como se muestra en el ejemplo anterior. En C#, debe realizar siempre la conversión al tipo adecuado al leer los valores del estado de vista.

Si intenta obtener del estado de vista un valor que no existe, no se iniciará ninguna excepción. Para asegurarse de que un valor está en el estado de vista, compruebe primero si el objeto existe. En el ejemplo siguiente se muestra cómo comprobar una entrada del estado de vista.

If ViewState("color") Is Nothing Then
    ' No such value in view state, take appropriate action.
End If
if (ViewState["color"] == null)
    // No such value in view state, take appropriate action.

Si intenta usar una entrada de estado de vista inexistente de alguna otra manera (por ejemplo, para examinar su tipo), se iniciará una excepción NullReferenceException.

Volver al principio de la página

Proteger el estado de vista

De forma predeterminada, los datos de estado de vista se almacenan en un campo oculto de la página y se codifican mediante base64. Además, se crea un valor hash de los datos de estado de vista mediante una clave de código (MAC) de autenticación de equipo. El valor hash se agrega a los datos de estado de vista codificados y la cadena resultante se almacena en la página. Cuando se devuelve la página al servidor, el marco de la página ASP.NET vuelve a calcular el valor hash y lo compara con el valor almacenado en el estado de vista. Si los valores hash no coinciden, se produce una excepción que indica que los datos de estado de vista pueden no ser válidos.

Al crear un valor hash, el marco de la página ASP.NET puede probar si los datos de estado de vista se han dañado o manipulado. Sin embargo, aun cuando no se produzca una manipulación, usuarios malintencionados pueden interceptar y leer los datos de estado de vista.

Usar MAC para calcular el valor hash del estado de vista

La clave MAC que se usa para calcular el valor hash del estado de vista se genera automáticamente o bien se especifica en el archivo Machine.config. Si la clave se genera automáticamente, se crea en función de la dirección MAC del equipo, que es el valor GUID único del adaptador de red en ese equipo.

A los usuarios malintencionados puede resultarles difícil usar técnicas de ingeniería inversa en la clave MAC basándose en el valor hash del estado de vista. Así, la codificación MAC es una manera confiable de determinar si se han cambiado datos de estado de vista.

En general, cuanto más larga sea la clave MAC que se utiliza para generar el valor hash, menos probable será que el valor hash sea el mismo para las diferentes cadenas. Cuando la clave se genera automáticamente, ASP.NET usa codificación SHA1 para crear una clave de gran tamaño. Sin embargo, en un entorno de batería de servidores web, la clave debe ser la misma en todos los servidores. Si la clave no es la misma y la página se devuelve a un servidor distinto del que creó la página, el marco de trabajo de la página ASP.NET provocará una excepción. Por tanto, en un entorno de batería de servidores web, debe especificar una clave en el archivo Machine.config en lugar de permitir que ASP.NET la genere automáticamente. En este caso, asegúrese de que crea una clave lo suficientemente larga como para proporcionar la seguridad suficiente para el valor hash. Cuanto más larga sea la clave, sin embargo, más tiempo tardará la creación del valor hash. Por tanto, debe sopesar las necesidades de seguridad y las necesidades de rendimiento.

Cifrar el estado de vista

Aunque la codificación MAC ayuda a evitar la manipulación de los datos de estado de vista, no impide que los usuarios los vean. Puede impedir que otras personas vean estos datos de dos maneras: transmitiendo la página por SSL y cifrando los datos de estado de vista. Exigir el envío de la página por SSL puede ayudar a evitar que las personas no autorizadas examinen los paquetes de datos y obtengan acceso a ellos.

Sin embargo, el usuario que solicitó la página podrá seguir viendo los datos de estado de vista porque SSL descodifica la página para mostrarla en el explorador. Esto resulta adecuado si no le preocupa que los usuarios autorizados tengan acceso a datos de estado de vista. Sin embargo, en algunos casos, los controles pueden usar el estado de vista para almacenar información a la que ningún usuario debería tener acceso. Por ejemplo, la página podría contener un control enlazado a datos que almacena los identificadores del elemento (claves de datos) en el estado de vista. Si estos identificadores contienen información confidencial, como los identificadores de los clientes, debe cifrar los datos de estado de vista además de o en lugar de enviar la página por SSL.

Para cifrar los datos, establezca la propiedad ViewStateEncryptionMode de la página en true. Si almacena información en el estado de vista, puede usar las técnicas habituales de lectura y escritura, ya que la página se encarga de las operaciones de cifrado y descifrado. El cifrado de los datos de estado de vista puede afectar al rendimiento de la aplicación. Por tanto, no debe usar el cifrado a menos que lo necesite.

Cifrado del estado de control

Los controles que utilizan el estado de control pueden requerir que ese estado de vista se cifre llamando al método RegisterRequiresViewStateEncryption. Si algún control de la página requiere el cifrado del estado de vista, se cifrarán todos los estados de vista de la página.

Codificación del estado de vista por usuario

Si un sitio web autentica usuarios, puede establecer la propiedad ViewStateUserKey en el controlador de eventos Page_Init para asociar el estado de vista de la página con un usuario específico. Esto ayuda a evitar ataques con un solo clic, en los que un usuario malintencionado crea una página Web válida, que ya contenga el estado de vista de una página previamente creada. El atacante atrae a continuación a una víctima para que haga clic en un vínculo que envía la página al servidor utilizando la identidad de la víctima.

Cuando se establece la propiedad ViewStateUserKey, la identidad del atacante se utiliza para crear el hash del estado de vista de la página original. Cuando se consigue que la víctima reenvíe la página, los valores hash serán diferentes porque las claves de usuario son diferentes. Se emitirá un error de comprobación en la página y se producirá una excepción.

Debe asociar a la propiedad ViewStateUserKey con un valor único para cada usuario, como el nombre o identificador de usuario.

Proteger la configuración en un entorno de hospedaje compartido

En un entorno de hospedaje compartido, los usuarios malintencionados podrían modificar las propiedades de administración de estado, lo que podría afectar a otras aplicaciones del equipo. Esta acción se puede llevar a cabo mediante la modificación directa del archivo Machine.config, la modificación mediante las clases de configuración y utilizando otras herramientas de configuración y administración. Puede ayudar a impedir las modificaciones en la configuración de la aplicación cifrando las secciones de los archivos de configuración. Para obtener más información, vea Cifrar información de configuración mediante una configuración protegida

Referencia de clase

ViewState

Proporciona un objeto de diccionario para conservar valores entre las solicitudes de la misma página.

PageStatePersister

Proporciona un medio para definir un mecanismo personalizado que permite almacenar la información de estado de vista, como en una base de datos de SQL Server.

Volver al principio de la página

Vea también

Conceptos

Información general sobre la administración de estados de ASP.NET

Recomendaciones de administración de estado de ASP.NET

Referencia

Volver al principio de la página