Stocker le viewstate sur le serveur plutôt que le client

Contenu du snippet

Par défaut ASP.net stocke le viewstate dans un champ caché du formulaire coté client, ce bout de code permet d'enregistrer cette valeur côté serveur dans une propriété static. Attention si l'application redemarre le viewstate sera alors perdu, j'ai posté ce code seulement pour montrer le concept, mais en production si vous avez vraiment besoin de stocker le viewstate sur le serveur plutot que le client (ce qui est très rare) il est conseille de l'enregistrer dans une base de donnée ou tout autre espace de stockage persistant. De plus comme je supprime le viewstate de la collection l'utilisateur risque de rencontrer des problèmes s'il joue avec le bouton retour et refait la même requête.

La source récupere la valeur non sérializé du viewstate le stock sur le serveur avec un identifiant unique et écrit dans un champ caché seulement cet identifiant unique.

UPDATE : ASP.net fait ce comportement nativement avec le SessionPageStatePersister : http://msdn2.microsoft.com/en-us/library/system.web.ui.sessionpagestatepersister.aspx

Source / Exemple :


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Generic;

/// <summary> 
/// This class save the viewstate value of each request on the WebServer. 
/// Don't use this on a server production ! If the application restart all the viewstates 
/// information will be loosed. You should save the viewstate in a DataBase or in any persistent storage. 
/// </summary> 
public class ServerViewStatePage : Page
{
    private static Object _lock = new object(); 
    private static Dictionary<Guid, Object> __viewstates;
    /// <summary> 
    /// Gets a dictionnary of viewstates stocked in the server. 
    /// </summary> 
    /// <value>The dictionary of viewstate stocked in the server.</value> 
    private static Dictionary<Guid, Object> _viewstates
    {
        get
        {
            lock (_lock)
            {
                if (__viewstates == null)
                    __viewstates = new Dictionary<Guid, Object>();
            }
            return __viewstates;
        }
    }

    /// <summary> 
    /// Loads any saved view-state information to the <see cref="T:System.Web.UI.Page"></see> object. 
    /// </summary> 
    /// <returns>The saved view state.</returns> 
    /// <remarks>Try to get the original viewstate if the __VIEWSTATEID hidden field was posted</remarks> 
    protected override object LoadPageStateFromPersistenceMedium()
    {
        if (!String.IsNullOrEmpty(Request.Form["__VIEWSTATEID"]))
        {
            Guid viewstateID = Guid.Empty;
            try
            {
                viewstateID = new Guid(Request.Form["__VIEWSTATEID"]);
            }
            catch
            {
                return null;
            }
            Object viewstate;
            if (_viewstates.TryGetValue(viewstateID, out viewstate))
                _viewstates.Remove(viewstateID); // Be carefull we remove the Viewstate so the user won't be able to make again the same request

            return viewstate;
        }
        else
        {
            return null;
        }
    }

    /// <summary> 
    /// Saves any view-state and control-state information for the page into a server Object. 
    /// </summary> 
    /// <param name="state">An <see cref="T:System.Object"></see> in which to store the view-state information.</param> 
    protected override void SavePageStateToPersistenceMedium(object state)
    {
        Guid viewstateID = Guid.NewGuid();
        _viewstates.Add(viewstateID, state);
        this.ClientScript.RegisterHiddenField("__VIEWSTATEID", viewstateID.ToString("N"));
    }

}

Conclusion :


Il suffit de mettre ce code dans le repertoire App_Code et de dériver votre page de Server ViewstatePage plutot que System.Web.UI.Page

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.