Programmeren in ASP.NET/Viewstate
Inleiding
[bewerken]Viewstate is een belangrijk onderwerp om te begrijpen en voor veel gebruikers (in het bijzonder voor oud-gebruikers van ASP), is het waarschijnlijk de feature die hen het meest programmeerwerk zal uitsparen. Het gaat hier over het bijhouden van de toestand van de objecten op je webpagina's.
Wat is viewstate?
[bewerken]Veronderstel dat je iets online wilt kopen. Je hebt je naam, adres en betalingsinformatie ingevuld, en doorgestuurd. Je stuurt het formulier op, en de server antwoordt dat er een fout is en je moet teruggaan en streepjes toevoegen aan je telefoonnummer of een ander detail. Je klikt op de "Back"-knop in je browser en alles wat je invoerde is weer leeg! De site in kwestie heeft je viewstate niet bijgehouden.
Een paar jaar geleden merkte niemand dit op, maar als tegenwoordig je site niet gebruiksvriendelijk genoeg is, zullen je bezoekers eenvoudig ergens anders gaan. Dus in plaats van mensen verplichten terug te gaan en hun informatie opnieuw in te geven, is het beter ze automatisch terug te sturen, en ervoor te zorgen dat het formulier klaarstaat met alle informatie erin, gereed om te wijzigen.
Dankzij viewstate kan een GridView ook na postback de gegevens nog steeds tonen, zonder opnieuw de databank te openen (als er geen wijzigingen zijn natuurlijk).
Het basisformulier
[bewerken]Hier is een basisformulier. Het doet niet echt veel. Je kan een naam invoeren en een kleur kiezen uit een lijst. Met deze gegevens wordt een zinnetje geproduceerd.
form1.aspx
<%@ Page Language="VB" %> <script runat="server"> Sub Page_Load(Sender as Object, E as EventArgs) If Request.Form("tbNaam") <> "" Then lblZin.Text = Request.Form("tbNaam") _ & " selecteerde " & Request.Form("ddlKleur") End If End Sub </script> <html> <head> <title>ASP.NET Viewstate voorbeeld #1</title> </head> <body> <form action="form1.aspx" method="post"> Voer je naam in: <input type="text" id="tbNaam" name="tbNaam" /> Kies een kleur: <select id="ddlKleur" name="ddlKleur"> <option>Rood</option> <option>Oranje</option> <option>Geel</option> <option>Groen</option> <option>Blauw</option> <option>Indigo</option> <option>Violet</option> </select> <input type="submit" id="btnSubmit" value="Submit" /> </form> <asp:label id="lblZin" runat="server" /> </body> </html>
Het werkt, maar na iedere indiening van het formulier verdwijnt de naam, en gaat de kleur weer naar rood.
Met viewstate
[bewerken]Nu je het gezien hebt op de klassieke manier, is hier de nieuwe ASP.NET manier:
form2.aspx
<%@ Page Language="VB" %> <script runat="server"> Sub btnSubmit_Click(Sender as Object, E as EventArgs) lblSentence.Text = txtName.Text & " selecteerde " _ & ddlColor.SelectedItem.Text End Sub </script> <html> <head> <title>ASP.NET Viewstate voorbeeld #2</title> </head> <body> <form id="frmViewState" runat="server"> Typ je naam: <asp:TextBox id="txtName" runat="server" /> Kies een kleur: <asp:DropDownList id="ddlColor" runat="server"> <asp:ListItem>Rood</asp:ListItem> <asp:ListItem>Oranje</asp:ListItem> <asp:ListItem>Geel</asp:ListItem> <asp:ListItem>Groen</asp:ListItem> <asp:ListItem>Blauw</asp:ListItem> <asp:ListItem>Indigo</asp:ListItem> <asp:ListItem>Violet</asp:ListItem> </asp:DropDownList> <asp:button id="btnSubmit" text="Verzenden" onClick="btnSubmit_Click" runat="server" /> </form> <asp:label id="lblSentence" runat="server" /> </body> </html>
Deze keer wanneer je het formulier indient, behoudt het alle waarden bij elke update. Merk op dat de twee pagina's bijna exact even lang zijn. Het ASP.NET-framework (en de server-controls) doet al het werk in de tweede. Je hoeft daarvoor zelf niets te doen.
Hoe werkt het?
[bewerken]ASP.NET voegt automatisch "viewstate" toe aan de pagina. Dit gebeurt via een verborgen formulierveld. Als je de broncode van het tweede formulier bekijkt in je browser, zie je een regel die er ongeveer als volgt uitziet:
<input type="hidden" name="__VIEWSTATE" value="dDwtMTA2Mzk5MTczNDt0PDtsPGk8Mz47PjtsPHQ8cDxwPGw8VGV4dDs+ O2w8Sm9obiBzZWxlY3RlZCBHcmVlbjs+Pjs+Ozs+Oz4+Oz6NaBGW1O3JUoxq0PX rlih3OZ2CTA==" />
Er werden line breaks toegevoegd om het leesbaar te houden.
De server zendt de staat van het formulier naar de client samen met het formulier zelf, in de vorm van dit verborgen veld. Het is belangrijk op te merken dat deze informatie niet op de server bewaard blijft en dat het niet gebeurt via ActiveX-controls of een Java-applet of een of andere client-side truc. De staat wordt behouden via standaard HTML.
Nadelen van viewstate
[bewerken]Het enige echte nadeel is de toename in de grootte van de pagina en het erop volgende POST-request. Dat kan de respons van de pagina vertragen. Daarom kan (en moet) je altijd viewstate uitschakelen waar die niet nodig is.
Dit doe je eenvoudig door het EnableViewState="false"-attribuut toe te voegen. Dit kan op meerdere niveaus, elk niveau kan het vorige overschrijven, en het is het dichtstbijzijnde niveau dat uiteindelijk telt.
Niveau van viewstate | waar uitschakelen | voorbeeld |
---|---|---|
één control | in de tag van de control | <asp:DataGrid EnableViewState="false" ... /> |
één pagina | in het @Page-directief | <%@Page EnableViewState="false" %> |
één toepassing | in web.config | <pages enableViewState="false" /> |
volledige machine | in machine.config | <Pages enableViewState="false" /> |
Dit zijn gevallen waarbij viewstate zeker niet nodig is:
- als de pagina niet naar zichzelf terugpost. Viewstate werkt dan toch niet.
- wanneer alle eigenschappen van de controls in het formulier vast ingesteld blijven.
- wanneer alle eigenschappen van de controls in het formulier bij elke aanvraag toch opnieuw ingesteld worden.
Variabelen behouden via viewstate
[bewerken]Het gebeurt dikwijls dat je in je pagina of in je user-control zelf variabelen definieert. Zo wil je bijvoorbeeld bij een datagrid bijhouden of je bezig bent toe te voegen of te wijzigen, of je wil bij het verwijderen eerst nog een panel tonen om te bevestigen, waarbij je het nummer van het te verwijderen record wil bijhouden.
Normaal gaat de waarde van een variabele telkens verloren als de pagina opnieuw aangemaakt wordt. Om deze waarde toch te behouden kan je ze bewaren in het Session-object, maar dat is eerder bedoeld om waarden door te geven aan andere pagina's. Een betere oplossing is deze variabelen te bewaren in de viewstate. Dit doe je met behulp van het Viewstate-object, dat een eigenschap is van elke pagina (en van elke control).
Dit gaat gemakkelijk als je van de variabele een property maakt, en als je dan in de getters en setters de Viewstate gebruikt. Hier is een voorbeeld voor een boolean:
Property AddingNew() As Boolean Get Dim o As Object = ViewState("AddingNew") If o Is Nothing Then Return False End If Return CBool(o) End Get Set(Value As Boolean) ViewState("AddingNew") = Value End Set End Property
Je kan dit ook gebruiken bij property's van usercontrols en custom controls, als je wil dat de waarde na postback automatisch behouden blijft.
Let op: in de expressie ViewState(“AddingNew”) is het woord “AddingNew” hoofdlettergevoelig!