asp.net - page - events asp net
¿Qué haces cuando no puedes usar ViewState? (10)
Esto también tiene problemas, porque tengo que anular explícitamente el valor de la sesión durante las devoluciones para no emular cómo funciona ViewState.
¿Por qué tiene que anular explícitamente el valor (aparte de la gestión de memoria, etc.)? ¿No es una opción verificar Page.IsPostback y hacer algo con la variable Session o no?
Tengo una página bastante compleja que construye dinámicamente controles de usuario dentro de un repetidor. Este repetidor debe estar vinculado durante el evento de la página Init antes de que se inicialice ViewState
o los controles de usuario creados dinámicamente no retendrán su estado.
Esto crea un Catch-22 interesante porque el objeto al que debo vincular el repetidor debe crearse en la carga de la página inicial y luego persistir en la memoria hasta que el usuario decida abandonarlo o guardarlo.
Como no puedo usar ViewState
para almacenar este objeto, pero lo tengo disponible durante Init, me he visto obligado a almacenarlo en Session.
Esto también tiene problemas, porque tengo que anular explícitamente el valor de la sesión durante las devoluciones para no emular cómo funciona ViewState
.
Tiene que haber una mejor forma de administración estatal en este escenario. ¿Algunas ideas?
Editar: algunas buenas sugerencias sobre el uso de LoadViewState
, pero sigo teniendo problemas con el estado que no se restaura cuando lo hago.
Aquí hay algo si la estructura de la página
Página -> UserControl -> Repeater -> N cantidad de UserControls creados dinámicamente.
Puse LoadViewState
reemplazado en el UserControl
principal, ya que está diseñado para ser completamente encapsulado e independiente de la página en la que se encuentra. Me pregunto si ahí es donde está el problema.
Sí, el tiempo de ejecución completará el estado de vista de los controles siempre que cree el número correcto de ellos. El estado de visualización de los controles se completará después de este evento.
¿En qué orden se llama LoadViewState? Agregué una firma de método anulada y no parece entrar en ella.
Tengo que anular explícitamente el valor de la sesión durante las no devoluciones para emular cómo funciona ViewState.
Todavía estoy confundido sobre por qué no puedes almacenar los objetos a los que te estás atacando durante la sesión. Si pudieras almacenar ese objeto en sesión, lo siguiente debería funcionar:
- En la primera carga, vincula tu control de usuario superior al objeto durante OnPreInit. Almacene el objeto en sesión. Viewstate se almacenará automáticamente para esos controles. Si tiene que vincular el control la primera vez en Page_Load, eso está bien, pero terminará teniendo dos eventos que llaman bind si sigue el siguiente paso.
- En la devolución de datos, vuelva a enlazar el control de usuario de usuario superior en el método OnPreInit con el objeto que guardó en la sesión. Todos sus controles deben volver a crearse antes de que se cargue viewstate. Luego, cuando viewstate se restaure, los valores se establecerán en lo que esté en viewstate. La única advertencia aquí es que cuando se vuelva a vincular en la devolución de datos, debe asegurarse al 100% de que se vuelva a crear la misma cantidad de controles. La clave para usar Repetidores, Gridviews, etc ... con controles dinámicos dentro de ellos es que tienen que recuperarse en cada devolución de datos antes de que se cargue viewstate. OnPreInit es generalmente el mejor lugar para hacer esto. No hay ninguna restricción técnica en el marco que dicte que debe hacer todo su trabajo en Page_Load en la primera carga.
Esto debería funcionar. Sin embargo, si no puede utilizar la sesión por algún motivo, tendrá que adoptar un enfoque ligeramente diferente, como almacenar lo que quiera en la base de datos después de vincular su control, extraerlo de la base de datos y volver a vincularlo de nuevo en cada devolución.
¿Me falta algún detalle obvio sobre tu situación? Sé que puede ser muy complicado explicar las sutilezas de la situación sin publicar código.
EDITAR: Cambié todas las referencias a OnInit a OnPreInit en esta solución. Olvidé que MS presentó este nuevo evento en ASP.NET 2.0. De acuerdo con la documentación del ciclo de vida de su página , OnPreInit es donde se deben crear / recrear los controles dinámicos.
1) probablemente haya una forma de hacer que funcione ... solo tienes que asegurarte de agregar tus controles al árbol en el momento correcto. Demasiado pronto y no obtienes ViewState. Demasiado tarde y no obtienes ViewState.
2) Si no puede resolverlo, ¿tal vez puede desactivar ViewState para la página del agujero y luego confiar solo en la cadena de consulta para los cambios de estado? Cualquier enlace que anteriormente era una devolución de datos sería un enlace a otra URL (o una devolución de datos-redirección).
Esto realmente puede reducir el peso de la página y hacer que sea más fácil evitar problemas con ViewState.
@DancesWithBamboo:
Si enlace dinámicamente los controles allí, ¿ASP.NET manejará automáticamente su estado? El problema al hacerlo en Page_Load es que viewstate ya está cargado y no agrega los controles dinámicos en el repetidor. ¿Pensaría que haría lo mismo en LoadViewState?
@Jonathan:
Sí, el tiempo de ejecución completará el estado de vista de los controles siempre que cree el número correcto de ellos. El estado de visualización de los controles se completará después de este evento.
Al crear controles dinámicos ... solo los rellene en la carga inicial. Afterwords recreé los controles en la devolución de datos en el evento de carga de página, y viewstate parece manejar la repoblación de los valores sin problemas.
El método LoadViewState en la página es definitivamente la respuesta. Aquí está la idea general:
protected override void LoadViewState( object savedState ) {
var savedStateArray = (object[])savedState;
// Get repeaterData from view state before the normal view state restoration occurs.
repeaterData = savedStateArray[ 0 ];
// Bind your repeater control to repeaterData here.
// Instruct ASP.NET to perform the normal restoration of view state.
// This will restore state to your dynamically created controls.
base.LoadViewState( savedStateArray[ 1 ] );
}
SaveViewState necesita crear la matriz savedState que estamos usando arriba:
protected override object SaveViewState() {
var stateToSave = new List<object> { repeaterData, base.SaveViewState() };
return stateToSave.ToArray();
}
No olvide vincular también el repetidor en Init o Load usando un código como este:
if( !IsPostBack ) {
// Bind your repeater here.
}
Siempre recreé mis controles dinámicos en el evento LoadViewState. Puede almacenar la cantidad de controles necesarios para crear en viewstate y luego crear dinámicamente muchos de ellos utilizando el método LoadControl dentro del evento LoadViewState. En este caso, tiene acceso al ViewState pero todavía no se ha restaurado a los controles en la página.
protected override void LoadViewState(object savedState)
{
// Put your code here before base is called
base.LoadViewState(savedState);
}
¿Es eso lo que querías decir? ¿O quisiste decir en qué orden se procesan los controles? Creo que la respuesta es cuasialeatoria.
Además, ¿por qué no puedes cargar los objetos a los que te vinculas antes de Page_Load? Está bien llamar a su capa de negocios en cualquier momento durante el ciclo de vida de la página, si es necesario, con la excepción de pre-render y cualquier cosa posterior.