ASP.NET : TextBox e l’attributo EnableViewState = false

Come sappiamo, il protocollo HTTP è di tipo state-less, ossia senza stato. Ciò vuol dire che non è possibile mantenere delle informazioni di stato tra una richiesta e l’altra, cioè ciascuna richiesta è completamente indipendente dalla precedente.

Con ASP.NET è stato introdotto il meccanismo del ViewState per superare questo limite. Oltre a poter essere abilitato o disabilitato a livello di pagina, è possibile anche gestirlo a livello di singolo controllo attraverso l’attributo EnableViewState.

Ci sono, però, alcuni controlli per i quali, pur settando EnableViewState = false, il loro valore viene mantenuto in seguito ad un Postback. Uno di questi è la semplicissima TextBox. Come è possibile ciò ?

Consideriamo una pagina aspx nella quale abbiamo una TextBox ed un Button.

<asp:TextBox ID="MyTextBox" runat="server" EnableViewState="false"/>
<asp:Button ID="MyButton" runat="server" Text="Click" onclick="MyButton_Click" />

Osserviamo che ho volutamente settato EnableViewState = false per il controllo TextBox. Se visualizziamo la pagina per la prima volta, avremo il seguente risultato.

4520.aspnet_viewstate1_4EBC81F0

Sino a qui non c’è nulla di strano; proviamo però a digitare del testo nella TextBox e cliccare sul bottone in modo da eseguire un Postback alla pagina. Pur non avendo abilitato l’uso delViewState sulla TextBox, il risultato sarà il seguente.

8054.aspnet_viewstate2_53BEBF9F

Come è possibile ciò ? In che modo lo stato del controllo è stato mantenuto pur avendo disabilitato la gestione del ViewState ?

Ebbene, la risposta è semplice; il controllo TextBox fa parte di un gruppo di controlli che implementano l’interfaccia IPostBackDataHandler e per i quali il valore immesso dall’utente viene trasferito attraverso l’header HTTP della richiesta POST al server e non viene immesso nel valore del campo hidden __VIEWSTATE.

Per rendercene conto, consideriamo una parte dell’HTML della pagina appena visualizzata…

<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNDQ4MjgxMTgxZGTNOC5r+KAS/pEPhvuwtdjw6Xg+DdjKydHf4P3AT9X6Rw==" />
</div>

<div class="aspNetHidden">

    <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwKy+bGFCQL1vtaTBwK4ooke2vLPwEEWgJUPhhabX+TyTbj9KOi3hO+pZVItu7X/OoU=" />
</div>
    <div>
        <input name="MyTextBox" type="text" value="Paolo" id="MyTextBox" />
        <input type="submit" name="MyButton" value="Click" id="MyButton" />

…ed utilizzando Wireshark, analizziamo il contenuto della richiesta HTTP POST eseguita verso il server al momento del Postback.

1385.aspnet_viewstate3_7CE657DD

Come si può osservare, al server viene trasmesso il valore del __VIEWSTATE ed a parte il valore immesso nella TextBox come un normale campo INPUT di una form.

In realtà, però, la proprietà Text della classe TextBox è implementata nel modo seguente.

public string Text
{
 get
 {
  string text=(string)ViewState["Text"];
  return (text==null)? String.Empty : text;
 }
 set
 {
  ViewState["Text"]=value;
 }
}

Ciò vuol dire che in fase di salvataggio e caricamento del valore di Text, comunque viene utilizzato il ViewState, indipendentemente dal fatto che esso sia abilitato o meno. Inoltre, laTextBox implementa il metodo LoadPostData dell’interfaccia IPostBackDataHandler attraverso il quale carica il valore immesso ricavandolo dalla collection dei dati post della form.

bool IPostBackDataHandler.LoadPostData(string postDataKey, 
                                   NameValueCollection postCollection)
{
    // recupera il valore dal ViewState
    string text1 = this.Text;
    // recupera il valore dalla collection post della form
    string text2 = postCollection[postDataKey];
 
    if (!text1.Equals(text2))
    {
        this.Text = text2;
        return true;
    }
    
    return false;
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s