Esperienze col ViewState

di Cristian Civera, in .NET,

In questo post illustrerò un po' di tips ricavati dalle mie esperienze e ore perse a cercare di capire il problema. Il ViewState è una bella cosa ma bisogna conoscere bene come lavora.

Se lavorate con controlli creati a runtime, vuoi perché interrogate un db o usate trasformazioni xslt, bisogna prestare attenzione ad una cosa. Il punto migliore dove crearli è OnInit della pagina (o del controllo). In questo modo siamo in "linea" con tutto il motore ASP.NET e non incapperemo in problemi di eventi e post dei dati. Si presenta però un problema. I controlli creati salvano nel viewState tutto quello impostato dopo l'init. Questo perché si presume (o presumo io) che i controlli siano stati creati dal parser ASP.NET quindi ogni proprietà e collezione non ha bisogno di essere salvata perché riimpostata ad ogni postback della pagina. Nel nostro caso però non è sempre così. A volte vogliamo risparmiare le interrogazioni del db. Per aggirare il problema ci sono due soluzioni:
- spostare la logica nel Load (a me non piace molto e si risolve in parte, ne parlerò dopo)
- separare creazione dei controlli dal caricamento dei controlli, rispettivamente nell'Init e nel Load

Veniamo a come funziona tutto sotto: dopo la fine della fase di Init viene richiamato per ogni controllo il metodo IStateManager.TrackViewState. Ogni controllo non deve far altro che marcare ogni precedente proprietà impostata come da non salvare nel viewState (al fine di ottimizzarne lo spazio).

L'oggetto StateBag (la proprietà ViewState di ogni controllo) per esempio, segna come non "Dirty" ogni successivo elemento aggiunto. Se volessimo impostare un elemento come da salvare anche se è stato impostato prima della chiamata a TrackViewState potremmo usare il metodo SetItemDirty, es:

ViewState.SetItemDirty("chiave", true);

Purtroppo alcuni controlli non usano solo lo stateBag ma sovrascrivono il metodo IStateManager.SaveViewState e quindi non possiamo intervenire. Il controllo DropDownList per esempio dispone della collezione Items. La classe ListItem dispone di una proprietà IsDirty, ma purtroppo è internal.

Per ultimo, guardate queste righe di codice:

TextBox t = new TextBox();
t.ForeColor = Color.Red;
Controls.Add(t);

oppure

TextBox t = new TextBox();
Controls.Add(t);
t.ForeColor = Color.Red;

Sono la stessa cosa? Io pensavo di sì, invece no. Init di un controllo avviene quando questo viene aggiunto alla collezione Controls. In base a quanto detto prima quindi, nel primo codice il ForeColor non verrà salvato nel viewState, nel secondo verrà salvato. Ovviamente sempre che EnableViewState sia true. Potrà sembrare banale ma a me sembra importante.

Commenti

Visualizza/aggiungi commenti

4 commenti | Condividi su: Twitter, Facebook, LinkedIn
Retek, il 29 febbraio 2004 alle 23:53
Il tuo post è veramente interessante: ora mi spiego il perchè il miei controlli aggiunti a run-time non rimanevano durante i postback!
Una cosa:
quando dici: "separare creazione dei controlli dal caricamento dei controlli, rispettivamente nell'Init e nel Load", cosa intendi per creazione e caricamento?
A prima vista sembra la stessa cosa..
Forse per creazione intendi l'instanziamento? (.. = new ClasseWebControl() e LoadControl(*.ascx) per gli userControl)
e per caricamente tutte quelle procedure che che vanno a "riepire" il controllo con proprietà e codice html?
Saresti così gentile da fare un esempio?

grazie mille!
Michele
Ricciolo, l'1 marzo 2004 alle 10:46
Per creazione intendo istanziamento e aggiunta del controllo alla collezione.
Per caricamento intendo, quello dei dati, delle proprietà ecc.
Pensa per esempio ad un datagrid, creazione, istanziamento del DataGrid e aggiunta alla collezione.
Caricamento, generalmente nel Page_Load si mette un bel
if (!IsPostBack)
bindDataGrid()
dani10, il 20 maggio 2004 alle 16:55
Ti rimando a questo Forum mi puoi dare una mano ,,,

http://forum.html.it/forum/showthread.php?s=&threadid=655771

Grazie
Daniele Bochicchio, il 20 maggio 2004 alle 17:23
le risposte sono date su questo forum, non per altri in giro per il web. se non ti va bene, ti adegui comunque, ma per cortesia, non scadiamo nella banalità.

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese