Solucionar el estado de vista es un error no válido con ASP.NET

En este artículo se presentan técnicas para depurar y resolver problemas con el estado de vista en Microsoft ASP.NET aplicaciones.

Versión del producto original:   ASP.NET
Número KB original:   829743

Introducción

View statees una característica de ASP.NET que permite a las páginas conservar automáticamente el estado sin depender del estado del servidor (por ejemplo, estado de sesión). Sin embargo, los problemas relacionados con el estado de vista pueden ser difíciles de depurar. En la mayoría de los casos, cuando se producen problemas con el estado de vista, recibe el siguiente mensaje de error en el explorador web, con poca indicación de lo que podría estar causando el problema:

El estado de vista no es válido para esta página y puede estar dañado

En este artículo se describen algunas técnicas que se pueden usar para la depuración y para resolver problemas con el estado de vista.

Comprobar que no se está ejecutando con problemas que se han corregido

Se solucionaron varios problemas de estado de vista con ASP.NET revisiones y service pack 1.0, y esas correcciones también forman parte de ASP.NET 1.1. Asegúrese de que ha aplicado las correcciones más recientes antes de realizar un seguimiento de los problemas que ya se han resuelto. Puede obtener las últimas actualizaciones de Microsoft .NET Framework desde aquí: Descargar .NET Framework.

Establecer el atributo validationKey si se está ejecutando en una granja de servidores web

En una granja de servidores web, cada solicitud de cliente puede ir a un equipo diferente en cada devolución. Debido a este comportamiento, no puede dejar el validationKey atributo establecido en AutoGenerate en el Machine.config archivo. En su lugar, debe establecer el valor del atributo en una cadena fija compartida por todas las validationKey máquinas de la granja de servidores web.

Para obtener más información acerca de este problema, vea Troubleshooting Invalid viewstate issues.

No almacenar tipos generados dinámicamente en estado de vista en una granja de servidores web

Cuando ASP.NET compila archivos dinámicamente, los archivos se crean en ensamblados con nombres aleatorios (por ejemplo, un nombre de archivo puede jp395dun.dll). Si ejecuta una granja de servidores web, los mismos archivos se compilarán en ensamblados con nombres aleatorios diferentes. Normalmente, esto no es un problema porque nadie hace suposiciones en esos nombres de ensamblado. Pero si alguna vez pone un tipo compilado dinámicamente en estado de vista mediante la serialización binaria, el nombre del ensamblado se incluirá como parte de los datos de estado de vista. Cuando ese estado de vista se envía más adelante a un servidor diferente de la granja de servidores web, el estado de vista no se puede deserializar porque usa nombres de ensamblado diferentes.

La mejor solución a este problema es evitar el uso de la serialización binaria. La serialización binaria usa muchos recursos incluso cuando no se produce este problema. En su lugar, limite el estado de vista a una combinación de matrices, pares, tripletes y tipos simples (por ejemplo, cadenas, int y otros tipos). System.Web.UI.Pair y System.Web.UI.Triplet son tipos de contenedor simples que el motor de estado de vista puede procesar de forma eficaz.

Una solución alternativa para evitar este problema es mover los tipos que almacena en estado de vista a un ensamblado precompilado, ya sea en la carpeta Bin o en la Global Assembly caché. Esta corrección no aborda el rendimiento, pero garantiza que el ensamblado tenga el mismo nombre en todos los equipos.

Nota

Si almacena tipos de datos complejos en estado de vista y experimenta este problema, la información de la pila de llamadas contendrá pilas similares a las siguientes:

[FileNotFoundException: Could not load file or assembly 'App_Web_fx--sar9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.]
 System.RuntimeTypeHandle._GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) +0
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +72
System.RuntimeType.PrivateGetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +58
System.Type.GetType(String typeName, Boolean throwOnError) +57
System.Web.UI.ObjectStateFormatter.DeserializeType(SerializerBinaryReader reader) +192 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +943 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +384 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +198 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +210 
System.Web.UI.ObjectStateFormatter.DeserializeValue(SerializerBinaryReader reader) +198 
System.Web.UI.ObjectStateFormatter.Deserialize(Stream inputStream) +142

El propósito de la característica de código de autenticación de máquina de estado de vista (MAC) es hacer imposible que los clientes envíen una solicitud que contenga un estado de vista malintencionado. De forma predeterminada, esta característica está habilitada en la siguiente marca del Machine.config archivo.

enableViewStateMac="true"

La forma más sencilla de determinar si el problema con el que está tratando está relacionado con la característica MAC es desactivar la característica. Para ello, cambie la marca del archivo Machine.config por el código siguiente.

enableViewStateMac="false"

Si ya no obtiene errores de estado de vista, el problema está relacionado con la característica MAC.

Importante

Solo desactiva la característica MAC de estado de vista para ayudar a diagnosticar el problema. No debe mantener el mac de estado de vista desactivado para evitar el problema. Si es así, podría introducir agujeros de seguridad. Para obtener más información, vea Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication.

Si desactiva la característica MAC de estado de vista y, a continuación, usa el estado de vista para los controles que no codifican HTML (por ejemplo, un control Label), los atacantes pueden manipular los datos de estado de vista y pueden poner datos arbitrarios en estado de vista. Estos datos arbitrarios se descodifican y los usan los controles cuando representan la página publicada. Como resultado, los atacantes pueden insertar scripts en la aplicación a menos que trabajes para evitar el ataque. Por ejemplo, un atacante podría descodificar los datos, insertar script en los datos donde está un control Label y, a continuación, vincularlo desde un sitio web. Cualquier persona que haga clic en el vínculo sería víctima de un ataque de inyección de scripts que podría robar sus cookies de autenticación o id. de sesión. El script también podría permitir que un atacante modificara los datos de estado de los controles que usan el estado de vista y ataques específicos de la aplicación como resultado.

En general, Microsoft recomienda no desactivar la característica MAC de estado de vista a menos que tenga la seguridad de que tiene el estado de vista deshabilitado para todos los controles que no codifican html sus resultados (por ejemplo, controles DataGrid, controles DataList, controles Label y otros controles) o que siempre establece explícitamente sus valores en cada solicitud en algo que se sabe que es seguro.

Determinar exactamente qué excepción se produce cuando recibe el mensaje de error

Desafortunadamente, el mensaje de error de estado de vista no válido que se menciona en la sección Introducción de este artículo no es informativo. El mensaje de error se debe a que se produce una excepción cuando se está procesando el estado de vista. El problema es que la excepción se está consumando y sus detalles se pierden en el mensaje de error.

Mediante el uso de un depurador, puede determinar la excepción original. Para ello, debe adjuntar un depurador al proceso ASP.NET (Aspnet_wp.exe o W3wp.exe) y, a continuación, establecerlo para capturar todas las excepciones. El depurador probablemente se detendrá en algunas excepciones que no son relevantes, pero al final llegará a la excepción de estado de vista y proporcionará información útil para solucionar problemas.

Los siguientes pasos son un ejemplo que usa el depurador de tiempo de ejecución (Cordbg.exe).

  1. En un símbolo del sistema, ejecute el comando para asegurarse de que se le proporciona un buen punto de partida y, a continuación, vaya iisreset a una página del sitio.

  2. En un símbolo del sistema, ejecute cordbg.exe .

  3. En el símbolo del sistema, escriba pro y, a continuación, presione ENTRAR. Aparecerá una lista de procesos administrados. Debería ver el proceso de Aspnet_wp.exe o el W3wp.exe proceso. Tenga en cuenta su PID.

  4. En el símbolo del sistema, escriba un PID para adjuntarlo al proceso.

    Nota

    Reemplace PID por el PID que se señaló en el paso 3.

  5. En el símbolo del sistema, escriba ca e para Cordbg.exe para interrumpir todas las excepciones y, a continuación, escriba gto deje que se ejecute el proceso.

  6. Siempre que obtenga una excepción, escriba w para ver la pila. Si la pila es una excepción de estado de vista (busque en la pila), copie toda la excepción y la información de la pila de la ventana de comandos y, a LoadPageStateFromPersistenceMedium continuación, guarde la información. Esta información puede ayudarle a comprender el problema. Si la excepción no está relacionada, escriba g.

Intente almacenar el estado de vista en la sesión

De forma predeterminada, el estado de vista se redondea mediante un <input type=hidden> campo que se envía al explorador. A continuación, el explorador envía el campo al servidor en la siguiente solicitud. En algunos casos, este estado de vista puede llegar a ser grande y ser una posible fuente de problemas. Algunos exploradores no pueden controlar un campo oculto tan grande (y la solicitud de gran tamaño resultante) y los exploradores pueden truncar el estado de vista. Al truncar el estado de vista, se produce un mensaje de error dañado de estado de vista. Es más probable que este comportamiento se produzca en exploradores más sencillos. Por ejemplo, este comportamiento puede producirse en un explorador en un PDA.

Para determinar si puede encontrarse con un problema de este tipo, intente almacenar el estado de vista en la sesión. En el ejemplo siguiente se muestra cómo hacerlo.

<%@ language=c# debug=true %> 

<script runat=server> 
protected override object LoadPageStateFromPersistenceMedium() 
{ 
    return Session["_ViewState"]; 
}

protected override void SavePageStateToPersistenceMedium(object viewState) 
{ 
    Session["_ViewState"] = viewState; 
}

void TextChanged(object o, EventArgs e) 
{ 
    Response.Write("TextChanged"); 
} 
</script> 
<form runat=server> 
<asp:button text=Test runat=server/> 
<asp:textbox ontextchanged=TextChanged runat=server/> 
<input type=hidden name=__VIEWSTATE> 
</form> 

La siguiente línea de código solo es necesaria en ASP.NET 1.0, para solucionar un error. En ASP.NET 1.1, no es necesario.

<input type=hidden name=__VIEWSTATE>

Determinar si el problema se debe al reciclaje de procesos de trabajo

Imagina la siguiente situación:

  • Está ejecutando ASP.NET en Microsoft Internet Information Services (IIS) 6.0.
  • El grupo de aplicaciones se ejecuta con una identidad que no sea la cuenta del sistema local, la cuenta de servicio de red o una cuenta de nivel administrativo.
  • El atributo validationKey del <machineKey> elemento se establece en AutoGenerate en el archivo de configuración.

En este escenario, el siguiente procedimiento provocará un error de estado de vista:

  1. Un usuario examina una página.
  2. El proceso de trabajo que hospeda la aplicación ASP.NET recicla.
  3. El usuario vuelve a la página.

La solución alternativa para este escenario es usar un atributo validationKey explícito en el archivo de configuración.

Referencias