Prefacio
Siempre que comprenda un poco ViewState, sabrá que ViewState en las páginas Asp.net generalmente se almacena en un campo oculto de la página:
Cuando navegamos por el archivo fuente de la página, vemos muchas cosas desordenadas (especialmente cuando la página tiene un DataGrid con una gran cantidad de datos, o un GridView en ASP.NET 2.0). tiempo, ese es ViewState.
Conocimientos básicos
Debido a que hay algunos cambios nuevos en el mecanismo de almacenamiento persistente de ViewState en ASP.NET 2.0, presentaré brevemente los aspectos relevantes.
En ASP.NET 1.1, solo se proporciona el mecanismo de persistencia del dominio oculto de la página, por lo que en algunos casos, debe dejar de usar ViewState. Imagínese si hay decenas de miles de registros en su DataGrid (no lo piense). esto es anormal) No es necesario (alguien lo ha encontrado). Si ViewState está habilitado, ¿está seguro de que su servidor IIS puede soportarlo y la red puede soportarlo? Por supuesto, puede cambiar su mecanismo de almacenamiento anulando el método Page.SavePageStateToPersistenceMedium(), pero no olvide anular Page.LoadPageStateFromPersistenceMedium(), son un par.
El mecanismo de persistencia del estado de vista predeterminado en ASP.NET 2.0 aún conserva la información de estado como una cadena codificada en Base64 en un elemento HTML oculto en la página (un elemento con el atributo de tipo establecido en "oculto"). Las páginas ASP.NET utilizan el objeto HiddenFieldPageStatePersister para realizar este trabajo y una instancia IStateFormatter para serializar y deserializar la información de estado del objeto. O, para clientes móviles con ancho de banda y recursos limitados, también puede usar la clase SessionPageStatePersister para almacenar el estado de vista de la página en el objeto Sesión en el servidor. De hecho, solo hay un mecanismo de persistencia de sesión más. estado de la página en la sesión en lugar de en la página, lo que supone un ahorro de ancho de banda.
Pero si desea tener una comprensión más profunda del mecanismo de persistencia de ViewState, debe conocer la clase abstracta PageStatePersister. Para conservar el estado de vista en un cliente que no puede admitir el mecanismo de persistencia de estado de vista existente, puede extender la clase PageStatePersister e introducir su propia clase. propios métodos de persistencia de estado de vista y puede utilizar adaptadores de página para configurar aplicaciones ASP.NET para que utilicen diferentes mecanismos de persistencia de estado de vista según el tipo de cliente al que se sirve la página. Las clases derivadas de la clase PageStatePersister deben anular el método abstracto Save para almacenar el estado de la vista y el estado de control en el medio de persistencia, y anular el método Load para extraer información de estado. Si necesita serializar el estado de la vista y el estado del control en cadenas, puede usar el objeto IStateFormatter al que se accede a través de la propiedad StateFormatter. Serializa y deserializa eficientemente la información del estado del objeto en cadenas codificadas en Base64. También puede anular la propiedad StateFormatter para proporcionar su propio mecanismo de serialización del estado del objeto. En mi código se explica cómo hacerlo. Lo comprenderá después de echarle un vistazo.
El
campo oculto
del mecanismo de persistencia ViewStateno se introducirá. Este es el predeterminado. Como se indica en el prefacio.
La sesión
solo necesita anular la propiedad PageStatePersister en ASP.NET2.0.
anulación protegida PageStatePersister PageStatePersister
{
conseguir
{
devolver nueva SessionPageStatePersister(Página);
}
}
Si necesita anular estos dos métodos de LoadPageStateFromPersistenceMedium en ASP.NET1.1:
objeto de anulación protegido LoadPageStateFromPersistenceMedium()
{
return Sesión["ViewState"];
}
anulación protegida nula SavePageStateToPersistenceMedium (objeto viewState)
{
Sesión["ViewState"] = viewState;
RegisterHiddenField("__VIEWSTATE", "");
}
La base de datos (mi ejemplo es SQL Server2000)
está en ASP1.1. Preste atención a la línea violeta a continuación. No sé cuál es su uso. Me deprimió durante varios días. . El siguiente código está copiado de mi código fuente. No es necesario que lo escriba así en absoluto, excepto los necesarios.
anulación protegida nula SavePageStateToPersistenceMedium (estado del objeto)
{
cadena viewStateID = "VIEWSTATE#" + Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
ClientScript.RegisterHiddenField("__VIEWSTATE","");//Tenga en cuenta
intentarlo
{
si (losFormatter == nulo)
{
losFormatter = nuevo LosFormatter();
}
StringWriter sw = nuevo StringWriter();
losFormatter.Serialize(sw, estado);
Common.ViewStateData vsd = nuevo ViewStateData();
vsd.ViewStateID = verStateID;
vsd.ViewState = sw.ToString();
da = nuevo acceso a datos();
error de cadena = da.SaveViewState(vsd);
Respuesta.Escribir(error);
}
captura (Excepción ex)
{
Respuesta.Escribir(ex.Mensaje);
}
}
objeto de anulación protegido LoadPageStateFromPersistenceMedium()
{
cadena viewState = cadena.Vacío;
intentar
{
si (losFormatter == nulo)
{
losFormatter = nuevo LosFormatter();
}
cadena stateID = Page.Request["__VIEWSTATE_KEY"].ToString();
da = nuevo acceso a datos();
viewState = da.LoadViewState(stateID);
}
atrapar
{}
return losFormatter.Deserialize(viewState);
}
Esta línea de código está básicamente bien en ASP2.0. ¿Por qué es básica? Porque es la línea anterior ClientScript.RegisterHiddenField("__VIEWSTATE","")
; .net1.1 Es factible. También me referí al código de otras personas y agregué esta línea. Después de agregar esta línea, solo hay un en la
página. Hay dos cosas de este tipo en el archivo fuente de la página después de ejecutarla
.
Está bien eliminar esa línea, así que no entiendo para qué se usa la declaración. Dímelo claramente. Pero no funciona en Asp.net2.0. Aparece el siguiente error:
La información de estado no es válida para esta página y puede estar dañada.
De todos modos, estaba confundido en ese momento. Nunca antes había encontrado un error de este tipo. y no encuentro nada buscando en Google, sí, no sé si esa frase está mal. Llevo dos días deprimido y el problema no se puede solucionar. Soy naturalmente estúpido. Al guardar el estado de la vista en la base de datos y leerlo desde la base de datos, no pude encontrar el error, así que pensé en el código una y otra vez, pero estaba un poco confundido acerca de esa línea. campo de "__VIEWSTATE", así que comenté esta línea y realmente funcionó. Todavía no entiendo para qué sirve esa línea.
Por supuesto, también podemos completar las funciones anteriores escribiendo una nueva subclase de PageStatePersister, que es nueva en ASP.NET2.0:
espacio de nombres PageAdapter
{
usando Sistema;
usando System.IO;
usando System.Security.Permissions;
usando System.Web;
usando System.Web.UI
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
clase pública DatabasePageStatePersister: PageStatePersister;
{
pública DatabasePageStatePersister (página página): base (página)
{}
//
// Cargar ViewState y ControlState.
//
anulación pública carga vacía ()
{
estado de vista de cadena;
IStateFormatter formateador = this.StateFormatter;
Acceso a datos da = nuevo Acceso a datos();
cadena stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
viewState = da.LoadViewState(stateID);
Estado del parPair = (Par)formateador.Deserialize(viewState);
ViewState = estadoPair.Primero;
ControlState = statePair.Second;
}
//
// Persiste cualquier ViewState y ControlState.
//
anulación pública anulación Guardar()
{
si (ViewState! = nulo || ControlState! = nulo)
{
si (Página.Sesión! = nulo)
{
cadena viewStateID = "VIEWSTATE#" + base.Page.Session.SessionID.ToString() + "#" + DateTime.Now.Ticks.ToString();
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
Estado del parPair = nuevo par(ViewState, ControlState);
IStateFormatter formateador = this.StateFormatter;
// Serializa el objeto statePair en una cadena.
string serializedState = formatter.Serialize(statePair);
ViewStateData vsd = nuevo ViewStateData();
vsd.ViewStateID = verStateID;
vsd.ViewState = estado serializado;
Acceso a datos da = nuevo Acceso a datos();
error de cadena = da.SaveViewState(vsd);
}
demás
throw new InvalidOperationException("Sesión necesaria para StreamPageStatePersister.");
}
}
}
}
Luego puede anular la propiedad PageStatePersister:
anulación protegida PageStatePersister PageStatePersister
{
conseguir
{
devolver nueva DatabasePageStatePersister(Página);
}
el archivo
no es muy diferente de la base de datos. Solo estoy hablando de ASP.NET2.0. Debería ser similar en ASP.NET1.1, pero no he escrito el código para depurar:
todavía uso el método. de escribir una nueva subclase de PageStatePersister:
espacio de nombres StreamPageAdapter.
{
usando Sistema;
usando System.IO;
usando System.Security.Permissions;
usando System.Web;
usando System.Web.UI;
//
// StreamPageStatePersister es un estado de vista de ejemplo
// mecanismo de persistencia que persiste en la vista y el control
// estado en el servidor web.
//
[AspNetHostingPermission(SecurityAction.Demand, Nivel = AspNetHostingPermissionLevel.Minimal)]
clase pública StreamPageStatePersister: PageStatePersister
{
público StreamPageStatePersister (página página): base (página)
{}
//
// Cargar ViewState y ControlState.
//
anulación pública carga vacía()
{
Corriente stateStream = GetSecureStream();
// Lee la cadena de estado usando StateFormatter.
Lector StreamReader = nuevo StreamReader (stateStream);
IStateFormatter formateador = this.StateFormatter;
cadena contenido de archivo = lector.ReadToEnd();
// Deserilize devuelve el objeto Pair que está serializado en
// el método Guardar.
Estado del parPair = (Par)formateador.Deserialize(fileContents);
ViewState = estadoPair.Primero;
ControlState = statePair.Second;
lector.Cerrar();
stateStream.Close();
}
//
// Persiste cualquier ViewState y ControlState.
//
anulación pública void Save()
{
si (ViewState! = nulo || ControlState! = nulo)
{
si (Página.Sesión! = nulo)
{
Corriente stateStream = GetSecureStream();
Escritor StreamWriter = nuevo StreamWriter(stateStream);
IStateFormatter formateador = this.StateFormatter;
Pair statePair = new Pair(ViewState, ControlState);
// Serializa el objeto statePair en una cadena.
cadena serializedState = formateador.Serialize(statePair);
escritor.Write(serializedState);
escritor.Close();
stateStream.Close();
}
demás
throw new InvalidOperationException("Sesión necesaria para StreamPageStatePersister.");
}
}
// Devuelve un Stream seguro para su entorno
privado Stream GetSecureStream().
{
ruta de cadena = @"d:a.txt";
FileStream fs = nuevo FileStream (ruta, FileMode.Open, FileAccess.ReadWrite);
devolver fs;
}
}
}
Simplemente anule la propiedad PageStatePersister:
anulación protegida PageStatePersister PageStatePersister
{
conseguir
{
devolver nuevo StreamPageStatePersister (Página)
;
A través de la breve introducción anterior, deberíamos tener cierta comprensión, pero lo que debemos entender es: en ASP.NET1.1 solo podemos completar las funciones anteriores reescribiendo age.SavePageStateToPersistenceMedium() y Page.LoadPageStateFromPersistenceMedium(); .NET1.1 En ASP.NET2.0, además de esto, también lo completamos escribiendo una nueva subclase de PageStatePersister y anulando la propiedad PageStatePersister. Por supuesto, no encontré ninguna diferencia si lees el siguiente contenido. , comprenderá que escribir una nueva subclase de PageStatePersister es de utilidad real.
Uso del adaptador de página
Dado que el mecanismo de persistencia del estado está relacionado con la representación adaptativa y la funcionalidad del lado del cliente, se proporciona MyPageAdapter para activar DatabasePageStatePersister de la aplicación ASP.NET. Finalmente, se proporciona un archivo de capacidades del navegador (.browser) para habilitar MyPageAdapter para una clase específica de clientes (en este caso, el navegador web predeterminado).
Para conocer estos contenidos, consulte el proyecto PageAdapter en el código fuente que proporcioné. Lo entenderás después de leerlo.
usando System.Security.Permissions;
usando System.Web;
usando System.Web.UI
espacio de nombres PageAdapter;
{
[AspNetHostingPermission(SecurityAction.Demand, Nivel = AspNetHostingPermissionLevel.Minimal)]
clase pública MyPageAdapter: System.Web.UI.Adapters.PageAdapter
{
anulación pública PageStatePersister GetStatePersister()
{
devolver nuevo PageAdapter.DatabasePageStatePersister(Page);
}
}
}
Finalmente, para habilitar el adaptador MyPageAdapter, debe crear un directorio llamado App_Browsers en el directorio raíz de la aplicación ASP.NET e incluir un archivo .browser que contenga la información de configuración (de hecho, todos estos se agregan cuando lo agrega). al proyecto Se completará automáticamente un archivo .browser en vs2005. El elemento
<refID del navegador="Predeterminado" >
<adaptadores de control>
<adaptador
controlType="Sistema.Web.UI.Página"
adaptorType="PageAdapter.MyPageAdapter" />
</controlAdaptadores>
</navegador>
</navegadores>
Esto se puede ver en el proyecto TestPageAdapter en el código fuente. Este proyecto se utiliza para demostrar el adaptador de página.
La conclusión
es relativamente simple y puede que no sea muy clara. En cuanto a las ventajas y desventajas de varios mecanismos de persistencia, no las he probado específicamente y el último elemento "Usar adaptador de página" no es un mecanismo de persistencia, pero utiliza un adaptador. Entonces no anularemos
el atributo PageStatePersister. Me parece que no es muy útil, porque podemos poner la acción de anular PageStatePersister en la clase base de la página y todas las demás páginas pueden heredar esta clase base. Cómo está en mi código. Es problemático usar este adaptador de página. Por supuesto, no sé mucho sobre el adaptador de página.
Además, una breve explicación de mi código fuente:
1. Proyecto PageAdapter
DatabasePageStatePersister.cs: una subclase de la clase PageStatePersister MyPageAdapter.cs: adaptador de página para acceder a la base de datos DataAccess.cs y ViewSate.cs, perteneciente a la clase auxiliar.
2. El proyecto StreamPageAdapter
es similar al anterior, por lo que no entraré en detalles.
3. Proyecto SaveStateToDatabase
StateInHiddenField.aspx: pruebe el mecanismo de almacenamiento predeterminado, es decir, puede ver muchas cosas desordenadas cuando mira. el archivo fuente de la página.
StateInSession.aspx: el mecanismo de almacenamiento es Session.
StateInDatabase.aspx: la base de datos del mecanismo de almacenamiento es el tipo de método de reescritura. Puede ser utilizado por asp.net1.1 y 2.0.
StateInDatabase2.aspx: escriba una nueva subclase de PageStatePersister y anule la propiedad PageStatePersister.
StateInFile.aspx: guarde ViewState en una carpeta en el servidor.
4. Proyecto TestPageAdater.
Utilizado para pruebas y adaptadores.