Siguiendo a mi post anterior, vamos a ver una técnica alternativa para conseguir la persistencia del ViewState en sesión.
La anterior técnica, nativa de ASP.NET 2.0 adolecía de varios problemillas, los más importantes son:
1.- No eliminaba del todo el ViewState, sólo una parte del mismo. En formularios Web con muchos controles el tamaño del ViewState sigue siendo considerable, si bien se reduce bastante.
2.- Sólo funciona en ASP.NET 2.0, pero no en versiones anteriores.
Voy a explicar a continuación una técnica alternativa que elimina estos problemas y tiene algunas ventajas a mayores.
Para conseguir manejar a nuestro antojo el ViewState podemos sobrescribir dos métodos importantes de la página: SavePageStateToPersistenceMedium y LoadPageStateFromPersistenceMedium. Como se deduce de su propio nombre estos métodos se llaman automáticamente por la infraestructura de páginas ASP.NET a la hora de almacenar y de recuperar el ViewState de una página respectivamente.
Dado que en nuestro caso lo que vamos a hacer es persistir el ViewState a memoria y de manera individual para cada usuario emplearemos una variable de sesión. Podemos usar una única variable para todas las páginas de modo que se sobrescriba cuando cambiemos de página, o bien podemos usar una variable diferente para cada página y así mantener incluso su estado entre varias visitas (más sobre esto luego). En el ejemplo que he preparado he usado esta segunda opción, por lo que defino el prefijo que llevarán todas estas variables:
private const string PREF_CLAVE = "SP_VWST_";
Le he llamado así para recordar con estas iniciales la palabra "Session Persisted ViewState".
Bien, ahora sobreescribimos el método protegido SavePageStateToPersistenceMedium, y lo dejaremos definido de la siguiente manera:
protected override void SavePageStateToPersistenceMedium(object state)
{
//base.SavePageStateToPersistenceMedium(state);
//Se almacena en Sesión (la base lo hace en un campo oculto)
Session[PREF_CLAVE + Request.RawUrl] = state;
}
Es decir, evitamos que se llame a la implementación por defecto de la base (la primera línea comentada) ya que si no se comportaría como siempre, y almacenamos el objeto de estado en una variable de sesión que se llamará con nuestro prefijo seguido por la URL de la página (para distinguirla del estado persistido de otras páginas). Así de sencillo.
Ahora sólo queda recuperar este estado cuando sea necesario. Para ello seguimos un procedimiento igual de simple, que consiste en sobrescribir el método LoadPageStateFromPersistenceMedium de la página, del siguiente modo:
protected override object LoadPageStateFromPersistenceMedium()
{
object state = Session[PREF_CLAVE + Request.RawUrl];
//Si no lo hay en memoria lo coge del campo oculto, aunque sólo debería darse en la primera llamada y aún así sería nulo...
return (state != null) ? state : base.LoadPageStateFromPersistenceMedium();
}
En este caso recuperamos el estado desde la variable de sesión anterior. Puede que esté vacío porque es la primeravez que pasamos por la página, en cuyo caso llamamos a la implementación por defecto de la clase base (Page) para que otorgue los valores iniciales correctos. También muy sencillo ¿verdad?
Conclusiones
Con esta técnica podremos persistir el estado de nuestras páginas en memoria desde cualquier versión de ASP.NET, lo cual brinda varias ventajas en ciertas circunstancias:
-
No se debe trasegar la información de estado entre los diferetes
postbacks, lo que
ahorra mucho ancho de banda y aumenta la velocidad en formularios con muchos controles. Por ejemplo, esta técnica aplicada a un formulario de una de las últimas aplicaciones que hemos hecho en
Krasis aumentó la velocidad del mismo de manera espectacular ya que contenía varias decenas de controles (era una entrada de datos muy compleja con muchos postbacks y efectos AJAX).
-
Con esta técnica sí se elimina por completo el ViewState, al contrario que en el caso del objeto PageStatePersister de ASP.NET 2.0, que sí deja parte del mismo en el formulario.
-
Al hacerlo de este modo podemos conservar el estado de una página aunque nos vayamos a otras y más adelante volvamos a la misma. Mientras la sesión esté activa podemos regresar a la página y los controles estarán exactamente como los dejamos porque el estado de los mismos están en la variable de sesión. Imagínate por ejemplo una página de búsqueda compleja, con muchas variables y valores compuestos que cuesta mucho configurar. Puedes hacerlo una vez y tenerlos así fijados siempre que regreses a la página (mientras no se borre la variable de sesión correspondiente).
He colocado aquí un archivo .cs con una clase que implementa esta técnica. Si quieres que una página tuya la soporte sólo tienes que heredar de esta clase en lugar de Page y ya está.
¡Espero que te resulte interesante! :-)