HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Egyedi adatok megőrzése két web hívása között


Példaprogram letöltése

14672 bájt

Képzeljük el a következő esetet: készítünk egy új web kontrolt, melynek az a feladata, hogy egy általunk megadott színt jelenítsen meg. A színt RGB formában, három számként adjuk meg a kontrol property-jein keresztül. A web oldalunkon arra is lehetőséget biztosítunk, hogy e property-k értéke növelhető, csökkenthető legyen. Minden erre irányuló kérést természetesen a web szerverünkön futó alkalmazás dolgoz fel. A probléma a következő lesz az alkalmazásunknál: e web kontrolnak a piros színösszetevője legyen mondjuk 128 alapértelmezett esetben. Ha a felhasználó azt a funkciót választja ki, hogy ez a szám növekedjen, akkor elindul egy új kérés az alkalmazásunk felé, melyben növelve lesz a 128. A felhasználó megkapja az eredményt, de ismét növelni akarná ezt az értéket, viszont az többé nem változik!
Ennek oka az, hogy amikor egy új kérés érkezik a web alkalmazásunkhoz, akkor ott a web kontrol létrejön és a piros szín megkapja az alapértelmezett 128-at. Ha ezt növelni kell, akkor megtörténik, de a lényeg, hogy minden egyes kérés kiszolgálásánál a 128 lesz növelve és nem egy már esetlegesen növelt érték kap ismét nagyobb értéket.
A probléma abból adódik, hogy új kontrolunk property-jeinek aktuális értéke nem kerül megőrzésre automatikusan két webes kérés között és így hibás működés lép fel programunkban. Ennek megoldásához azt kell elérnünk, hogy saját kontrolunk saját property-jeinek értékei is megmaradjanak.

Az ASP.NET-es alkalmazásainkban szerencsére erre is egyszerűen megvalósítható lehetőségünk van. Az alkalmazásunk amúgy is tárol minden kérésnél néhány a saját működéséhez szükséges adatot. Ezt észre sem vesszük, hacsak bele nem nézünk egy legenerált web oldal forráskódjába. Itt a Web Form-nál találunk egy __VIEWSTATE nevű rejtett mezőt:
<form name="Form1" method="post" action="WebForm1.aspx" id="Form1">
   <input type="hidden" name="__VIEWSTATE" value="dDwtODM4MzkyNTM4O3Q8O2w8aTwxPjs"/>
Ez lesz a mező, mely kódolva tárolja a programunkhoz szükséges változók aktuális értékét minden egyes webes kérés esetén. Így ha egy újabb kérés indul a webes alkalmazásunk felé, akkor a __VIEWSTATE értékét felhasználhatjuk arra, hogy a legutóbbi kérésnél lévő értékeket visszatöltsük a szükséges változókba és a programunk ott folytathassa futását, ahol abbahagyta, legalábbis a változók szempontjából.
A __VIEWSTATE közvetlen kezelésére szerencsére nincs szükségünk, így csak a megfelelő függvények használatára kell összpontosítanunk a feladat megvalósításának érdekében.
Ez előtt azonban tegyünk egy kis kitérőt és készítsük el a bevezetőben említett új webes kontrolt, melyet a TestWebControlLibrary projektben valósítottunk meg.
A kontrolban létrehozunk három property-t (ColorR, ColorG, ColorB) a három színösszetevő tárolásához.
A kontrol a következő HTML kódot generálja:
<div style="width:100; height:100; background-color:#808080"> </div><div align=center>#808080</div>
Amint az látható a három szín property-ből származó színt a background-color stílusnak kell megadnunk. Ehhez szükségünk lesz egy olyan függvényre, mely a három színösszetevőből a #808080 sztringet előállítja. Ez a függvény lesz a HtmlRgb.
    private string HtmlRgb(byte r, byte g, byte b)
    {
      return "#"+r.ToString("X2")+g.ToString("X2")+b.ToString("X2");
    }
Ezek után jöhet a fenti HTML kód létrehozása a Render függvényben.
    protected override void Render(HtmlTextWriter output)
    {
      RenderBeginTag(output);
      string color = HtmlRgb(colorR, colorG, colorB);
      output.Write("<div style=\"width:100; height:100; background-color:"+color+"\"> </div>");
      output.Write("<div align=center>"+color+"</div>");
      RenderEndTag(output);
    }
Ha itt most megszakítjuk a kontrol fejlesztését és nem rendelkezünk arról, hogy a három szín property értéke megmaradjon két webes hívás között, akkor a bevezetőben leírt problémával találkozhatunk.
Ezt elkerülendő felül kell írnunk két függvényt: a SaveViewState akkor kerül meghívásra, amikor saját adatainkat eltárolhatjuk a __VIEWSTATE-be, míg a LoadViewState akkor fut, ha onnan betöltésre kerülnek az adatok.
Mentésnél meg kell hívnunk az ős osztály SaveViewState függvényét annak érdekében, hogy minden olyan adat tárolásra kerülhessen, melyekre a kontrolunk ős osztályainak szüksége van. E függvény visszatérési értékeként kapunk egy object típusú változót. Az eredménnyel nem kell foglalkoznunk csak tárolnunk azt. Ezt követően tárolhatjuk a mi adatainkat is tetszőleges számban. Számunkra most a három szín property értékének tárolására van szükségünk. Az egészet egy olyan tömbbe tároljuk, melynek elemei object típusúak. Mindig a tömb első elemébe kerül az ős osztály által visszaadott érték és tömb további elemeibe a saját értékeink. Végül a függvény visszatérési értékként az így felépített tömböt kapja.
    protected override object SaveViewState() 
    {
      object[] state = new object[4];
      state[0] = base.SaveViewState();
      state[1] = colorR;
      state[2] = colorG;
      state[3] = colorB;
      return state;
    }
A LoadViewState függvénynél történik a beolvasás. Itt is először az ős osztály LoadViewState függvényét kell meghívnunk, majd ezt követően olvashatjuk be saját adatainkat és tárolhatjuk a szükséges változókba.
    protected override void LoadViewState(object savedState) 
    {
      if (savedState != null) 
      {
        object[] state = (object[])savedState;
        if (state[0] != null)
        {
          base.LoadViewState(state[0]);
        }
        if (state[1] != null)
        {
          colorR = (byte)state[1];
        }
        if (state[2] != null)
        {
          colorG = (byte)state[2];
        }
        if (state[3] != null)
        {
          colorB = (byte)state[3];
        }
      }
    }
Ezt a módszert használva kontrol bármilyen adata megőrizhető két webes kérés között, így az új kérésnél figyelembe lehet venni a legutóbbi kérésnél lévő adatokat, melyre a programunk helyes működése érdekében most szükségünk is van.
Végső próbaként tegyük meg a következőt: a WebForm1-en lévő WebCustomControl11 kontrolnál az EnableViewState property értékét állítsuk hamisra. Ezzel azt érjük el, hogy a kontrol LoadViewState és SaveViewState függvényei nem kerülnek meghívásra és ezzel a kontrol szín property-jeinek az értéke sem kerül megőrzésre. Futtassuk most így a programot és kattintsunk valamely színösszetevő növelését előidéző gombra többször egymás után. Jól megfigyelhető lesz, hogy ez a szín csak az első kattintásnál fog növekedni és tovább nem, mivel mindig az alapértéket növeljük amiatt, hogy az aktuális érték nem került megőrzésre.

Könyv
Ez a cikk megtalálható ebben a könyvben: C# Software Offline 2002 évkönyv 227. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |