2010-11-08 20 views
2

Lors de la création de contrôles personnalisés, j'ai vu deux modèles d'utilisation de viewstate. L'une consiste à utiliser les propriétés pour masquer l'accès viewstate en tant que données persistantes.Avec ASP.NET viewstate, existe-t-il une meilleure pratique pour quand dans le cycle de vie pour accéder à viewstate?

public bool AllowStuff 
    { 
     get 
     { 
      return (ViewState[constKeyAllowStuff] != null) ? 
       (bool)ViewState[constKeyAllowStuff] : false; 
     } 
     set { ViewState[constKeyAllowStuff] = value; } 
    } 

L'autre est d'utiliser des champs de membres privés et de passer outre la charge/méthodes SaveViewState sur le contrôle et gérer tout explicitement:

protected override object SaveViewState() 
{ 
    object[] myViewState = new object[2]; 
    myViewState[0] = base.SaveViewState(); 
    myViewState[1] = _allowStuff; 
    return myViewState; 
} 

protected override void LoadViewState(object savedState) 
{ 
    object[] stateArray = (object[])savedState; 
    base.LoadViewState(stateArray[0]); 
    _allowStuff = (bool)stateArray[1]; 
} 

(je coupe beaucoup de sécurité la vérification de la clarté , donc juste ignorer cela.)

Y a-t-il un avantage particulier à un procédé par rapport à l'autre? Je ne peux pas voir comment ils diffèrent beaucoup de performance sage. La version 1 est paresseuse, donc je suppose que vous économisez un peu si vous n'avez pas besoin de cette valeur particulière pendant une passe. La version 1 est aussi plus abstraite, cache mieux les détails. La version 2 est plus claire lorsque les données sont réellement valides et peuvent être lues ou modifiées (entre le chargement et l'enregistrement) car elles fonctionnent plus clairement dans le cycle de vie ASP.NET. Cependant, la version 2 a tendance à exiger davantage de code standard (une propriété, un champ privé de sauvegarde et une gestion viewstate à deux endroits), contrairement à la version 1 qui combine tout cela en un seul endroit.

Pensées alors?

Répondre

2

L'approche sur le terrain de parlementaire est souvent utilisé pour les objets qui ne sont pas directement accès au sac de l'État ViewState. Donc, dans un sens, j'utiliserais l'option un pour les contrôles personnalisés, les contrôles utilisateur ou les pages, ou tout ce qui a un ViewState ou une propriété similaire, mais utilise l'autre option pour un objet qui n'a pas directement accès à ViewState (comme un classe que vous voulez pouvoir "sérialiser" et stocker dans viewstate). Par exemple, les contrôles personnalisés utilisent cette approche pour stocker l'état des objets enfants qui ne référencent pas directement viewstate.

HTH.

+0

lorsque vous travaillez avec webforms je toujours suivre le modèle de la propriété qui enveloppe l'état d'affichage, et je passerais cette propriété soutenu viewstate autour de mon habitude mise en œuvre du modèle de MVP. –

1

Fist de tout ce que je voudrais utiliser ControlState et non VIEWSTATE il fonctionne correctement si dans un récipient qui a l'état d'affichage éteint.

alors je remplacer init, SaveControlState, LoadControlState et DataBind.

et assurez-vous d'enregistrer que le contrôle utilise l'état de contrôle-à-dire Page.RegisterRequiresControlState (ce)

oh et l'avantage est que votre commande est plus robuste (utilisateur ne peut pas visser aussi facilement) et fonctionnera lorsque dynamiquement chargé et à travers postbacks « mieux »

+0

Je devrais probablement utiliser l'état de contrôle plus, mais je me sens si sale le faire. Comme si j'accédais au viewstate secret et invulnérable. En fait, nous avons parfois des problèmes avec ce que vous avez mentionné, comment voulez-vous dire qu'il fonctionnera mieux pour le chargement dynamique et à travers les publications? – CodexArcanum

+0

fondamentalement, je voulais simplement dire que si vous écrivez correctement, cela fonctionnera, même si l'état d'affichage est éteint, même si c'est dans un panneau de mise à jour, ou il y a un rappel ajax, etc .. –

+0

vous allez faire partie d'un callback ajax ScriptManager sm = ScriptManager.GetCurrent (Page); si (sm == null) { throw new InvalidOperationException ("Un ScriptManager est nécessaire sur cette page"); } base.OnPreRender (e); ScriptManager.RegisterHiddenField (this, this.ClientStateID, ""); –