230 likes | 321 Views
Tilstandsstyring. Motivation ViewState EventTarget, EventArgument. Motivation. Normalt er internettet et tilstandsløst (stateless) miljø … I kontrolbaserede modeller skal tilstande overføres i forbindelse med hver post-back Mange HTML-elementer medsender ingen værdier i en POST
E N D
Tilstandsstyring • Motivation • ViewState • EventTarget, EventArgument
Motivation • Normalt er internettet et tilstandsløst (stateless) miljø … • I kontrolbaserede modeller skal tilstande overføres i forbindelse med hver post-back • Mange HTML-elementer medsender ingen værdier i en POST • table, span, div, p, li, osv. • Hvis en kontrols værdi sættes på serveren og efterfølgende returneres til klienten, hvordan sendes denne værdi så tilbage igen ved post-back? • Hvis klienten ændrer/trigger i en kontrol, hvordan håndteres ændringen/hændeslen så ved post-back?
Eksempel • Betragt en tilstandsløs version af applikationen • what happened? • list box was filled on server • returned to client, client selected an item, triggered post-back • on post-back, list box is empty and selected item is forgotten! "markér"
Løsning — ViewState • ASP.NET anvender et skjult element: __ViewState • elementet genereres sammen med hver side • indeholder en base64-krypteret streng med supplerende tilstandsinformationer
Kontrol af ViewState • Kan sættes på hver kontrol • Er som standard sat, så kontroller opfører sig forventeligt • Hvordan slås ViewState fra? • sæt kontrollens EnableViewState–egenskab til falsk • sæt side-attributen, så ViewState slås fra for alle kontroller på siden • hvorfor slå ViewState fra? Komplekse kontroller, som fx grids kan indeholde store datamængder, som skal overføres hver gang siden genlæses … <%@ Page Language="C#" EnableViewState="False" %> <html> <!-- ... -->
Indlæsning af ViewState Page lifecycle PreInit • Kontroller genlæses automatiskvha. ViewState, når side-objektetdannes • Før Page_Load-hændelsen Themes initialized, master pages applied, control skins applied Init InitComplete CreateChildControls (if IsPostBack) Control/View state loaded (if IsPostBack) PreLoad Load
Brug af ViewState • ViewState kan også anvendes til at gemme klient-/applikations-tilstand • Side-objektet tilbyder ViewState-egenskaben (key/value-par) • data bevares ved post-backs til den samme side public partial class ShoppingPage : System.Web.UI.Page { private ArrayList cart; protected void Page_Load(object sender, EventArgs e) { // Indlæs aktuel kurv fra State: cart = (ArrayList) this.ViewState["Cart"]; if (cart ==null) // Første kald – skab ny kurv: cart =new ArrayList(); } . . // Andre metoder .
Hændelseshåndtering • Yderligere skjulte felter anvendes til hændelseshåndtering • __EventTarget indeholder hændelseskildens id • __EventArgument indeholder parameterværdier til hændelsen
Tilstandsstyring • Session state • Application state • Caching
Motivation • Applikationer håndterer forskellige slags data • Kunder, produkter, ordrer, personer, … • Collections • DataSets • DataTables • XML-dokumenter • I internet-verdenen håndteres data på serversiden • Er vi nødsaget til at genskabe/genindlæse hver gang eller kan vi bevare tilstanden etellerandet sted?
Eksempel • I Census Data applikationen indlæses census.txt igen og igen • ved første kald og igen ved hvert post-back … protected void Page_Load(object sender, EventArgs e) { // Find den rigtige sti, uanset applikationens placering: string filename = Path.Combine( System.AppDomain.CurrentDomain.BaseDirectory, Path.Combine("App_Data", "census.txt")); namesCollection = Program.ReadCensusData(filename);
Løsning • Vi kunne anvende ViewState – meromkostning ved nettrafik • data sendes frem og tilbage (langsomt) • ASP.NET tilbyder bedre server-side alternativer: • Session state: individuel tilstand bevares pr. klient i hele sessionens livstid • Application state: global tilstand bevares i hele applikationens livstid • Cache state: global tilstand, (fortrinsvis read-only data) bevares i et tidsrum bestemt af ASP.NET
Eksempel • Lad os optimere Census Data applikationen ved at cache namesCollection samlingen på serveren • vi anvender Cache, da data er statisk og globalt … private List<FamilyName> namesCollection; protected void Page_Load(object sender, EventArgs e) { namesCollection = this.Cache["namesCollection"]; if (namesCollection == null) { // Første kald til siden // Find stien, uanset applikationens placering: string filename = Path.Combine( System.AppDomain.CurrentDomain.BaseDirectory, Path.Combine("App_Data", "census.txt")); namesCollection = Program.ReadCensusData(filename); this.Cache["namesCollection"] = namesCollection; }
Faldgruber — Application State • Voldsom brug af Application State hæmmer skalérbarheden • Opdateringer af Application State kræver lås (Lock/Unlock) • Ihukom, at web-applikationer er trådede • Application State repræsenterer en potentiel kritisk sektion • Application State er typisk read-only for at undgå dette this.Application.Lock(); if (this.Application["visits"] == null) this.Application["visits"] = 0; else this.Application["visits"] = 1 + (int) this.Application["visits"]; this.Application.UnLock(); System.Diagnostics.Debug.WriteLine( this.Application["visits"] );
Faldgruber — Session State • Session state anvendes til styring af klient-tilstand • indkøbskurve, fakturaer, persondata … • Dette virker kun, hvis hver klient entydigt kan identificeres • hertil anvendes cookies; men disse kan slås fra • Session State virker i ASP.NET uanset om cookies er slået fra eller ej, blot følgende angives: web.config <configuration> <system.web> <sessionStatecookieless="true"/> </system.web> </configuration> "AutoDetect" anvender cookies, hvis det er muligt
4.3 Flersidede Sites • Teknikker til flersidede applikationer
Motivation • De fleste hjemmesider består af flere sider • Hvordan bevæger vi også fra side til side?
Gå til anden side … • To forskellige tilgange: • Response.Redirect(url); • Server.Transfer(page); • Response.Redirect(url) • url kan være lokal eller en fuldt kvalificeret URL: "http://..." • returnerer til klienten og beder browseren redirigere til den givne URL • Server.Transfer(page) • siden skal være lokal, i den samme eller i en anden ASP.NET applikation • mere effektiv end Response.Redirect; men begrænset til lokale sider
Eksempel • Når en bruger klikker på login-knappen, tjekkes password, ogbrugeren viderestilles, hvis ok … • hvordan overføres data mellem siderne? • i dette tilfælde anvendes Context State… protected void btnLogin_Click(object sender, EventArgs e) { DataTier.DataAccess data; long id; string pwd; if (!this.IsValid) return; id = long.Parse(this.txtStudentID.Text); pwd = this.txtPassword.Text; data = new DataTier.DataAccess("Students.mdb"); if (data.passwordMatch(id, pwd)) { this.Context.Items["ID"] = id; this.Context.Items["DataAccess"] = data; this.Server.Transfer("StudentInfo.aspx", true /* bevar tilstand*/); } else this.lblErrorMsg.Text = "Incorrect id or password..."; }
Destinationssiden • Destinationssiden udtrækker simpelthen data fra Context … protected void Page_Load(object sender, EventArgs e) { // Er brugeren kommet direkte hertil? object obj = this.Context.Items["ID"]; if (obj == null) this.Response.Redirect("Login.aspx", true /* afslut nu */); long id; DataTier.DataAccess data; id = System.Convert.ToInt64(obj); data = (DataTier.DataAccess) this.Context.Items["DataAccess"]; this.DataGrid1.DataSource = data.GetStudent(id); this.DataGrid1.DataBind(); } protected void btnLogout_Click(object sender, EventArgs e) { this.Server.Transfer("Login.aspx", false /* nulstil tilstand */); }
Overførsel af data mellem sider • Der er flere mulige teknikker … • Tilføj en QueryString til URL'en og brug Response.Redirect • data begrænser sig til URL-kompatible strenge • Gem data midlertidigt i Context state og brug Server.Transfer • virker fint, hvis data ikke skal bevares over længere tidsrum • Gem data i Session State • God løsning, hvis data skal gemmes over længere tidsrum • Virker med begge redirigeringsmetoder http://www.site.com/test.aspx?name=joe&age=42 Context.Items["data"] = ...;
Hvad så? • Øvelse #4
<blank> • …