Custom Controls e ViewState

Mi sono avventurato nello sviluppo di un Custom Server Control per ASP.NET abbastanza complesso (almeno per la mia esperienza in questo campo che è limitata a qualche controllino che non gestiva postback): ho sviluppato un ConnectionStringBuilder, per inserirlo nelle pagine di installazione del blogging engine al quale sto contribuendo, SubText.

Ho dovuto affrontare un problema abbastanza sottile: il controllo contiene dei DropDown che vengono popolati direttamente nella sua prima visualizzazione, ma sul postback i valori non venivano mantenuti.
Abilitando il Trace ho notato che il ViewState era sempre di 0 byte.

Invece, il DropDown popolato sul postback manteneva correttamente i valori caricati.

Ho impiegato parecchio tempo per trovare la soluzione: dopo i primi 15 minuti su Google non sono riuscito a trovare nessuna menzione del problema, quindi significa solo due cose:

  1. è un problema banalissimo e quindi nessuno ne ha mai parlato
  2. è un problema che quasi nessuno incontra e quindi, nessuno ne parla

In realtà la risposta sta nel mezzo: pochi sviluppano custom controls complessi, e la soluzione al problema era ovvia sapendo come funziona il ViewState.

Una controllo salva il ViewState per tutti i controlli figli, ma solo a partire dal momento nel quale questi vengono salvati nella collection dei Controls.

Quindi prima di popolare la dropdown list avrei dovuto collegarla a cascata fino al controllo principale, non solo al suo parent.

Riporto due snippet trovati sul post di Scott Mitchell (per Igor, è il fondatore di 4GuysFromRolla ) che mi ha salvato da una figura meschina con i colleghi sviluppatori del progetto SubText.

Cosa ho fatto (e, a quanto pare, ha fatto pure lui) --- ATTENZIONE: E' SBAGLIATO ---:

public class MyControl : WebControl, INamingContainer
{
  ...

  
protected override void CreateChildControls()
  {
    DropDownList ddl = 
new DropDownList();
    
if (!Page.IsPostBack)
      
// do data binding to some database...

    
Controls.Add(ddl);
  }
}

E come va fatto correttamente

public class MyControl : WebControl, INamingContainer
{
  ...

  
protected override void CreateChildControls()
  {
    DropDownList ddl = 
new DropDownList();
    Controls.Add(ddl);   
// Add the control FIRST

    
if (!Page.IsPostBack)  // Bind data AFTER
      // do data binding to some database...
  
}
}

Per la spiegazione originale: Control Building and ViewState Lesson for the Day , e Composite controls that do their own databinding

powered by IMHO 1.3

posted @ martedì 24 gennaio 2006 18:49

Print

Comments on this entry:

# Re: Custom Controls e ViewState

Left by Simone Busoli at 25/01/2006 01:23
Gravatar
Grazie per il post, molto interessante!

# re: Custom Controls e ViewState

Left by simone at 25/01/2006 01:26
Gravatar
prego :-)

# re: Viewstate e controlli dinamici

Left by Crad's .NET Blog at 17/05/2007 02:48
Gravatar
Comments have been closed on this topic.
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011