¿Cómo utilizar IsPostBack y ViewState para mejorar la eficiencia de la página?
IsPostBack es un atributo bool de la clase Página, que se utiliza para determinar si la solicitud del formulario actual es la primera vez. Cuando IsPostBack=true, significa que no es la primera vez.
La solicitud, la llamamos devolución de datos, significa la primera solicitud cuando IsPostBack=false. Dentro del marco ASP.NET, existen muchos escenarios para determinar IsPostBack, como
LoadAllState y otras operaciones que deben completarse en la devolución de datos. Cuando usamos WebForm para desarrollarnos, a menudo juzgamos IsPostBack en Page_Load, porque
Para la primera solicitud, se ejecutará Page_Load, y para las solicitudes que no sean las primeras, se ejecutará Page_Load. ¿Por qué hay varias solicitudes para el mismo formulario? ASP.NET introdujo servicios.
Los eventos del lado del servidor, controles que admiten eventos del lado del servidor, realizarán solicitudes para el formulario actual, por lo que en muchos casos debemos distinguir si es la primera solicitud del formulario.
2 Conclusión de IsPostBack
Mi análisis del procesamiento relevante en el código fuente. Net llegó a las siguientes conclusiones:
Conclusión ① Para las páginas migradas mediante Server.Transfer, IsPostBack=false.
Conclusión ② Modo de publicación Si no hay ningún valor de solicitud en la solicitud, es una solicitud. Form = null, IsPostBack = false; si no hay ningún valor solicitado en la solicitud, es
request. QueryString = nulo, IsPostBack = falso.
Conclusión (3) Si se evalúa una cadena de consulta o un formulario, las claves de la cadena de consulta o el formulario no tienen "__VIEWSTATE" ni "__EVENTTARGET" también.
__VIEWSTATEFIELDCOUNT", y ninguna clave es nula, el valor comienza con "__VIEWSTATE" y no hay un par clave-valor con el valor "__EVENTTARGET", entonces IsPostBack
=false.
p>
Conclusión ④ Cuando se utiliza el modo de redirección para migrar a la autoimagen, IsPostBack=false
Conclusión ⑤ Cuando se accede al atributo PreviousPage, IsPostBack. =true de la página de origen.
Conclusión ⑥La página de destino es IsPostBack=false cuando se envía entre páginas.
Conclusion Server.Execute migra la página con IsPostBack=false
.La conclusión se está ejecutando en la página. Durante el proceso, la DLL correspondiente se actualizó y la estructura de árbol de la página también cambió. En este caso, IsPostBack=false durante la solicitud. Las conclusiones se pueden entender de la siguiente manera: En términos generales, si se realiza la solicitud, si no se solicita ningún valor, IsPostBack = false Si requiere evaluación pero no incluye algunas características especiales, como "__VIEWSTATE"
. Se devolverán claves o valores especiales, IsPostBack=false, después de cada solicitud. El cliente devuelve algunos campos ocultos especiales "__VIEWSTATE"). Si las reglas anteriores no se pueden determinar correctamente, se requiere un procesamiento especial. Incluye transferencia del servidor, redirección y retorno cruzado. Ejecutar y enviar. Los elementos de la página se cambian y se vuelven a compilar. En términos generales, basta con recordar la conclusión anterior.
Si está interesado o tiene dudas, continúe consultando el proceso de razonamiento de IsPostBack a continuación.
3 proceso de razonamiento de IsPostBack
A continuación se explica cómo analizar IsPostBack en función de él. Marco neto. Con respecto a la inferencia de estas conclusiones, he realizado experimentos relevantes para demostrar la exactitud de la inferencia, porque
Debido a razones de espacio, estos códigos de prueba no se reflejan. Además, es imposible reflexionar. Net framework, solo necesita enumerar los fragmentos de código relevantes y explicar la base de la inferencia.
Además, debido a mi nivel limitado, mi comprensión del código todavía tiene algunas deficiencias. Marco neto. Por favor corrígeme si lo encuentras. Gracias.
publicbool es PostBack
{
get
{
if (this._requestValueCollection == null)
{
Devuelve falso
}
if (this._isCrossPagePostBack)
{
Devuelve verdadero
}
if (this_pageFlags[8])
{
Devuelve falso
}
Retorno (
(
(this.Context . ServerExecuteDepth lt= 0) ||
((this.Context controlador! = nulo) amp; amp
(base.GetType() == this.Context.Handler.GetType())) amp _fPageLayoutChanged
);
}
}
Tratamos cada juicio como una sección y hacemos el siguiente análisis.
3.1 Este. _requestValueCollection == null
if (this._requestValueCollection == null)
{
return false
}
Se puede ver que cuando _requestValueCollection es igual a nulo, IsPostBack es igual a falso.
Existe el siguiente código en page.processrequestmain (bool, bool):
If (this.PageAdapter!=null)
{
Esto. _requestValueCollection = esto. adaptador de página . DeterminePostBackMode();
}
Otro
{
Este. _requestValueCollection = esto. DeterminePostBackMode();
}
Adaptador de página. DeterminePostbackMode finalmente llama a Page.DeterminePostBackMode. Veamos cómo implementar Page.DeterminePostBackMode.
Colección protegida de valores de nombres virtuales internos DeterminatePostBackMode()
{
if (this.request == null)
{
Devolver nulo
}
Si (this.
Context.PreventPostback)
{
Devolver nulo
}
namevaluecollectioncollectionbasedonmethod = this. GetCollectionBasedOnMethod(false);
if(collectionBasedOnMethod == null)
{
Devolver nulo
}
bool flag = false
cadena[]valores = collectionBasedOnMethod. obtener valores ((cadena) nulo);
si (valor! = nulo)
{
int longitud = valor. Longitud;
for(int I = 0; i lt longitud; i)
{
if(valor[i].StartsWith("__VIEWSTATE ", StringComparison.ordinal)||
(valores[i] == "__EVENTTARGET "))
{
bandera = verdadero
Romper;
}
}
}
if((collectionBasedOnMethod[" _ _ VIEWSTATE "]= = null) amp; amp(collectionBasedOnMethod[" _ _ VIEWSTATEFIELDCOUNT "]== = null)) amp;
((collectionBasedOnMethod[" _ _ objetivo del evento "]== = null) amp; amp! bandera))
{
return null
}
if (this. request . querystringtext . index of(
HttpResponse .RedirectQueryStringAssignment, StringComparison.Ordinal)! = -1)
{
collectionBasedOnMethod = null
}
Devolver colecciónBasedOnMethod
}
La función devuelve nulo significa IsPostBack=false. Realice el siguiente análisis de cada lugar donde se devuelve nulo en las funciones anteriores.
3.1.1 Éste. contexto. solicitud == nulo
if (este. contexto. Solicitud == nulo) {retorno nulo} esto. Context.Request == null solo debería ocurrir en circunstancias excepcionales.
En circunstancias normales, los objetos HttpContext y HttpRequest se crearán en httpruntime.
3.1.2 esto. Context.PreventPostback
Si (this.
Context.PreventPostback) {return null} PreventPostback se utilizará en HttpServerUtility. Transferencia y su generación
El código es el siguiente:
Transferencia pública nula (ruta de cadena)
{
bool preventPostback = este. _Contexto. PreventPostback
Esto. _Contexto. PreventPostback = true
Esto. transfer(ruta, verdadero);
Esto. _Contexto. PreventPostback = PreventPostback;
}
Establecer contexto. Preventpostback = true al llamar al servidor. Transferencia de migración de pantalla. La conclusión aquí es ①: para migración con servidores. transferir, mudarse a.
Página con IsPostBack=false.
3.1.3 collectionBasedOnMethod = = null
namevaluecollectioncollectionbasedonmethod = esto. GetCollectionBasedOnMethod(false);
if(collectionBasedOnMethod == null)
{
Devolver nulo
}
Después de llamar a la página. getCollectionBasedonMétodo, determina su valor de retorno. Si su valor de retorno es nulo, IsPostBack es falso.
Página. getCollectionBasedonMethod se define de la siguiente manera:
Colección interna de nombre y valor GetCollectionBasedOnMethod(bool dontreturnull)
{
if (this._request.HttpVerb == HttpVerb.post)
{
Si (!dontReturnNull amp amp!this._request.HasForm)
{
Devolver nulo
}
Devuelve esto. _preguntar. formulario;
}
if (!dontReturnNull amp amp!this._request.HasQueryString)
{
return null p >
}
Devuelve esto. _preguntar. QueryString
}
Como se puede ver en el código anterior, el valor de retorno es nulo _ request.hasform = null o _ request.hasquerystring = null. Aquí viene la conclusión ②: si usa ②: modo de publicación,
No hay ningún valor solicitado en la solicitud, es decir, solicitud. Form = null, IsPostBack = false; si no hay ningún valor de solicitud en la solicitud, es decir, Solicitud, obtenga el método.
QueryString = nulo, luego
IsPostBack=false .
3.1.4((collectionBasedOnMethod[" _ _ VIEWSTATE "]= = null) amp; amp(collectionBasedOnMethod[" _ _ VIEWSTATEFIELDCOUNT "]= = null)) amp; amp
((collectionBasedOnMethod[" _ _ event target "]= = null) amp; amp! flag)
bool flag = false
cadena[]valores = colecciónBasedOnMethod. obtener valores ((cadena) nulo);
si (valor! = nulo)
{
int longitud = valor. Longitud;
for(int I = 0; i lt longitud; i)
{
if(valor[i].StartsWith("__VIEWSTATE ", StringComparison.ordinal)||
(valores[i] == "__EVENTTARGET "))
{
bandera = verdadero
Break;
}
}
}
El significado del código anterior es determinar si el par clave-valor solicitado no existe Clave cuyo valor comienza con "__VIEWSTATE" o es "__EVENTTARGET". Por ejemplo, el siguiente método de solicitud Obtener tendrá flag=true.
…/predeterminado aspx? _ _ViewState
…/aspx predeterminado? __EVENTTARGET
es el modo de adquisición "?__VIEWSTATE = "con __VIEWSTATE como clave solicitada y su valor es " ", pero "?__VIEWSTATE" considerará su clave como "nula" y su valor es " ".
" _ _VIEWSTATE"
If (
((collectionBasedOnMethod[" _ _ VIEWSTATE "]= = null) amp; amp(collectionBasedOnMethod[" _ _ VIEWSTATEFIELDCOUNT "]= = null)) amp; amp
((collectionBasedOnMethod[" _ _ event target "]= = null) amp; amp! flag))
{ p>
Devuelve nulo
}
La condición anterior significa que no hay "__VIEWSTATE", "__EVENTTARGET" y "__VIEWSTATEFIELDCOUNT" en la clave solicitada si el indicador es falso. , devolverá nulo.
La bandera falsa significa que ninguna clave es nula, el valor comienza con "__VIEWSTATE" y no hay ningún par clave-valor con el valor "__EVENTTARGET".
Aquí viene la conclusión ③ Si se evalúa QueryString o Form, las claves en QueryString o Form no tienen "__VIEWSTATE" y "__EVENTTARGET" también.
__VIEWSTATEFIELDCOUNT" y no hay ningún par clave-valor cuya clave sea nula y cuyo valor comience con "__VIEWSTATE" y cuyo valor sea "__EVENTTARGET", entonces IsPostBack= =
Error.
p>3.1.5 this. request . querystringtext . índice de (respuesta http. RedirectQueryStringAssignment, StringComparison. Ordinal)! de (respuesta http .RedirectQueryStringAssignment, StringComparison! = -1)
{
collectionBasedOnMethod = null
}
El valor de httpredirectQueryStringAssignment . es "_ _ redir = 1", lo que significa que si QueryStringText contiene "_ _ redir = 1",
será redirigido a la URL si IsPostBack es verdadero. no está incluido, se agregará "_ _ redir = 1" a la URL. Generalmente, migramos a páginas según las solicitudes. La redirección debe ser IsPostBack=false. Hay un caso especial en el que usamos request.redirect para migrar a la página actual.
Página e IsPostBack es verdadero. Cuando esto suceda, agregue "__redir=1 0" a la URL en request.Redirect. ProcessRequestMain, se volverá a ejecutar
Se considera que IsPostBack es falso.
La conclusión aquí es reaccionar. El modo de redireccionamiento se utiliza para migrar a la imagen propia, IsPostBack=false.
En este punto, quizás te preguntes por qué se necesita un manejo especial al utilizar Response. Redirecciona al árbol de diagnóstico "Migrar a su propia pantalla y por qué las respuestas no funcionan". Redirigir a "Mover a otra pantalla".
Cuando se utiliza Respuesta. Redirecciona a "Migrar a otra imagen, respuesta". Formulario = nulo y respuesta. QueryString=null, para que puedas juzgar IsPostBack=false. Pero utilice
al responder. El modo de redireccionamiento migra a selfie y responde. Cadena de consulta
3.2 esto. _isCrossPagePostBack
si (this.
_isCrossPagePostBack)
{
Devuelve verdadero
}
_ iscrossPagepostback se establecerá en el atributo PreviousPage de la página, el código específico es el siguiente:
Página pública página anterior
{
Obtener
{
…
ITypedWebObjectFactory vPathBuildResult = (ITypedWebObjectFactory) administrador de compilación. GetVPathBuildResult(this. contexto,
this. _ ruta de la página anterior
if (tipo de (página)); IsAssignableFrom(vPathBuildResult.InstancedType))
{
Esto. _ Página anterior = (Página) vPathBuildResult. crear instancia();
Esto. _Página anterior. _ isCrossPagePostBack = true
Esto. Server.Execute(this._previousPage, TextWriter. Null, true, false);
}
}
Devuelve esto. _ anteriorPage
}
}
Cuando se produce un envío entre páginas, IsCrossPagePostBack de la página de origen se establecerá en verdadero cuando se acceda a la propiedad PreviousPage. La conclusión a la que se llega aquí es que (5) se produce el envío entre páginas.
(CrossPagePostBack), al acceder a la propiedad PreviousPage, el valor IsPostBack=true de la página de origen.
3.3 esto. _pageFlags[8]
if (this._pageFlags[8])
{
return false
}
En la página. ProcessRequestMain, hay un fragmento de código a continuación para asignar un valor a _pageFlags[8].
else if(!this.IsCrossPagePostBack)
{
Ruta de ruta virtual = null
if (this._ requestValueCollection[" _ _ página anterior "]!=null)
{
prueba
{
ruta = VirtualPath. CreateNonRelativeAllowNull(
DecryptString(this. _ requestValueCollection[" _ _ página anterior "]);
}
catch (excepción de contraseña)
{
This._page flags[8]= true;
}
if ((ruta!= null) amp; amp(ruta! = this. request . CurrentExecutionFilePathObject))
{
esta. banderas de página[8]= true;
this.
_ anteriorPagePath = ruta
}
}
}
_pageFlags[8] es verdadero cuando se produce una excepción durante el descifrado, que es El caso es menos probable que suceda. Ignorémoslo por ahora y centrémonos en otra situación, combinando todas las condiciones de esta situación.
IsCrossPagePostBack = false amp amp_ requestValueCollection[" _ _ página anterior "]! = ruta de amperaje nulo! = null amp amp(path!=
this. request . CurrentExecutionFilePathObject Cuando se produce un envío entre páginas, IsCrossPagePostBack=false de la página de destino). En este momento, la página de origen
envía "__PREVIOUSPAGE" y otra información a la página de destino, por lo que _ RequestValueCollection[" _ _ página anterior "]! = null. El
CurrentExecutionFilePathObject solicitado actualmente se genera en función de la ruta de la página de destino, que es diferente del objeto de ruta generado usando _ RequestValueCollection[" _ _ Página anterior "].
Aquí se concluye que la página de destino es IsPostBack=false cuando se envía entre páginas. ¿Por qué necesita hacer esto para la página de destino de CrossPagePostBack?
¿Qué pasa con el tratamiento? Cuando se produce CrossPagePostBack, la información de la página de origen se enviará a la página de destino. En este momento, solicite. ¡forma! = =null y contiene __VIEWSTATE y otras claves según otras reglas.
Se considerará IsPostBack=true, por lo que se debe realizar un juicio especial en la página de destino de CrossPagePostBack.
3.4(this.Context.ServerExecuteDepth lt= 0) ||(((this.Context.Handler!= null) amp; amp(base.GetType() ==
Esto. Context.Handler.GetType()))
En HttpServerUtility, existe el siguiente código para operar el contexto. ServidorExecuteDepth.
ejecutar public void (ruta de cadena, escritor TextWriter, bool preserveForm)
{
…
Probar
{
Esto. _Contexto. profundidad de ejecución del servidor;
handler = this. _Contexto. instancia de aplicación . MapHttpHandler(this. _context, request. Tipo de solicitud, ruta 3, nombre de archivo,
useAppConfig
}
Finalmente
);{
Esto. _Contexto. el servidor ejecuta profundidad-;
}
}
Hay operaciones similares para el contexto. ServerExecuteDepth en la utilidad del servidor http. Ejecución interna.
HttpServerUtilidad. Ejecute la llamada.
HttpServerUtility. Aspectos internos de la ejecución. Se puede ver desde este contexto. ServerExecuteDepth representa la profundidad de ejecución en el contexto de llamada Server.Execute.In
. ServerExecuteDepth > Cuando el servidor. Ejecución > 0. Además, después de llamar al servidor. ejecutado, el objeto de la página original todavía se almacena en el contexto. El mango, es decir, la base. ObtenerTipo()! = esto. Context.Handler.GetType(). Entonces para el servidor. Ejecutar, this. context. server ejecutar profundidad
((this. context. handler! = null) Esta condición es falsa. La conclusión aquí es que la página migrada usando Server.Execute tiene IsPostBack=false< / p>
Pregunta, ¿por qué es necesario hacer un juicio especial sobre el servidor? La razón es que cuando se utiliza el servidor, los campos ocultos en la página de origen se enviarán = vacíos
El. La clave que contiene __VIEWSTATE se juzgará como IsPostBack=true según otras reglas
3.5. _fPageLayoutChanged
Desde el significado literal de esta variable, la página El diseño ha cambiado
El fragmento de código en la página es el siguiente:
Private void LoadAllState()
{
…
cadena s = (cadena) segundos;
integer = entero. parse(s, NumberFormatInfo. información invariante);
this. p>
}
significa que cuando el HashCode obtenido es inconsistente con el HashCode almacenado en ViewState, fPageLayoutChanged =true GetTypeHashCode() devuelve un HashCode. >
Y este método se genera cuando se compila aspx. El valor de retorno solo cambiará cuando los elementos de la página cambien.
Durante este período, su DLL correspondiente se ha actualizado. Y la estructura de árbol de la página también ha cambiado. En este caso, IsPostBack=false se determina al solicitar si el servidor lo devuelve después de enviarlo
Cuando ingresa directamente una dirección de página. la URL para acceder a la página.
En este momento, el objeto de página creado en el lado del servidor. La propiedad IsPostBack es falsa.
Al enviar esta página, algunos valores. y el material de los controles de la página se envía de vuelta al servidor.
El servidor luego crea un objeto de página nueva
y lee la información devuelta por ViewState al servidor. >
La propiedad IsPostBack de este nuevo objeto de página es verdadera.
De repente se me ocurrió
Si conoces el ciclo de vida de un objeto de página, es fácil de entender.
Puedes consultar la información relevante.
Sepa cuándo se activa cada evento de página.
Y qué obra se realizó en distintos momentos.
Por ejemplo, cuándo leer el estado de la vista.
Cuándo ejecutar eventos de control
¿Cuándo guardar el estado de la vista?
Cuándo renderizar la página (es decir, enviar la página al cliente)
Esto es más problemático de decir> _ lt
Pruébelo usted mismo ~ ~ p>
Si comprende esto
Entonces tendrá una comprensión general del mecanismo de regresión de la página ASP.NET.
Esto también será útil para resolver algunos problemas en el futuro