Comment conserver l'état d'une variable (session et viewstate)

Contenu du snippet

Sur le forum, j'ai vu à plusieurs reprises que certaines personnes ne comprenait pas pourquoi, leur variable disparaissait.

En effet, ils avaient saisi ce code :

Private maVariable As Integer

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
maVariable += 1
Response.Write(maVariable)
End Sub

Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
maVariable += 2
Response.Write(maVariable)
End Sub

et quand il cliquait une première fois sur un bouton, le nombre correspondant apparaissait mais par contre, lorsqu'il recliquait dessus, les nombres ne s'ajoutaient pas.
Par exemple, on clique le bouton 2, ca affiche 2 puis on click sur le bouton 1 ça affiche 1 alors que l'on s'attendait à 3 (maVariable += 1)

Le problème vient que les applications webform sont en mode deconnecté, donc quand l'utilisateur fait le postback (le deuxième click sur le bouton) il commence au début donc mavariable vaut 0

Il existe deux solutions à ce problème

Le ViewState :

au lieu d'ecrire Private maVariable As Integer ecrivez :
Private Property maVariable() As Integer
Get
Return CType(viewstate("MaVariable"), Integer)
End Get
Set(ByVal Value As Integer)
viewstate("MaVariable") = Value
End Set
End Property

Ce code est un peu plus long, mais aux deuxieme click sur le bouton, la page affichera 3 !
Grace à cette méthode, asp.net va ecrire de facon codé la variable à l'interieur d'un champ caché :
<input type="hidden" name="__VIEWSTATE" value="dDwtNTMwNzcxMzI0O3Q8cDxsPE1hVmFyagUAyRfkR" />
Ainsi une fois le postback effectué asp.net saura la valeur de maVariable

Mais cette méthode a deux inconvénients :
Le premier c'est que le champ caché alourdit considérablement le poids de la page, mais avec les connexions de plus en plus rapide, c'est de moins en moins un problème. Mais le deuxième inconvénient c'est que le viewstate n'accepte pas tous les objets, il n'accepte que les objets serializable, et ce n'est pas le cas de tous les objets, par exemple le code suivant n'est pas valide :
Dim oTable As New HtmlTable
Viewstate("oTable ") = oTable
Asp.net nous renverra ce message d'erreur :
Le type 'System.Web.UI.HtmlControls.HtmlTable' doit être marqué comme Serializable ou utiliser un TypeConverter autre que ReferenceConverter dans le viewstate.

L'Autre méthode qui permet de résoudre ce dernier problème est les sessions: il suffit de modifier le code comme ceci :
Private Property maVariable() As Integer
Get
Return CType(session("MaVariable"), Integer)
End Get
Set(ByVal Value As Integer)
session("MaVariable") = Value
End Set
End Property

Ce code fonctionnera avec tous les objets possibles et imaginables, le seul petit problème, c'est que la variable est stockée sur le serveur, d'ou une surcharge de travail.

Source / Exemple :


'viewstate : 

    Private Property maVariable() As Integer
        Get
            Return CType(viewstate("MaVariable"), Integer)
        End Get
        Set(ByVal Value As Integer)
            viewstate("MaVariable") = Value
        End Set
    End Property

'Session : 

    Private Property maVariable() As Integer
        Get
            Return CType(session("MaVariable"), Integer)
        End Get
        Set(ByVal Value As Integer)
            session("MaVariable") = Value
        End Set
    End Property

Conclusion :


si vous avez des remarques sur cette explication n'hésitez pas :)

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.