Кратко съдържание


Управление на състоянието



страница33/33
Дата23.07.2016
Размер10.53 Mb.
#1889
1   ...   25   26   27   28   29   30   31   32   33

Управление на състоянието


Уеб страниците се прехвърлят чрез HTTP протокола. Те не запазват състо­янието си, тъй като не знаят дали заявките идват от един и същ клиент. Страниците се създават наново при всяко обръщение към сър­въра. Ако не се използваха допълнителни механизми за управление на състоянието (state management), възможностите на уеб приложенията биха били много ограничени.

В класическите ASP приложения този проблем се решава по няколко начина, чрез: бисквитки (cookies), параметризирани адреси (query string), и чрез ASP обектите за приложение (application) и за сесия (session). В ASP.NET всички тези техники са на наше разположение, като възможно­стите им са обогатени в много отношения.

Подходите за управление на състоянието в уеб приложенията се разделят на две категории – от страна на клиента (Client-side) и от страна на сър­въра (Server-side). При управление на състоянието от страна на клиента, сървърът не пази информацията информация между заявките, а тя се съхранява на страницата или на компютъра на клиента.

Първо ще разгледаме Client-side техники – бисквитки, параметризирани адреси, скрити полета и ViewState. След това ще направим обзор на сървърните механизми за управление на състоянието на ниво приложение и ниво сесия.


Бисквитки (Cookies)


Бисквитката (cookie) е малко парче информация, изпратена от уеб сър­въра до клиентски браузър. Браузърът по подразбиране съхранява полу­чената бисквитка и от него се очаква да я изпраща обратно към сървъра при всяка следваща заявка. Информацията в нея може да е произволна, стига цялостният размер на бисквитката (информацията и мета данни за самата бисквитка) да не надвишава 4 KB. Нека да разгледаме някои от свойствата, с които се характе­ри­зи­рат бисквитките.

Свойства на бисквитките


Ето някои от по-важните свойства на бисквитките:

  • Expires - указва кога изтича валидността на бисквитката. Ако не се укаже, бисквитката се запазва само в паметта. Ако това свойство се зададе, бисквитката се записва на твърдия диск и се пази за време­то, което е указано. Когато браузърът изпраща дадена бисквитка, той проверява дали нейната валидност не е изтекла и ако така, той не я изпраща към сървъра, а я изтрива. Не трябва да забравяме, че потребителят може да изтрие бисквитката по всяко време.

  • Domain – областта от интернет адреси, на които може да се праща бисквитката. По подразбиране това е адресът, от който е дошла, но може да се укаже и друго. Браузърът изпраща само бисквитките, предназначени за поискания интернет адрес.

  • Path – път на адресите, до които може да се праща бисквитката. Бисквитката няма да се праща на адреси от по-високо ниво в дървото на директо­риите. Пример: ако пътят е /sites/stefan, тя няма да се прати на /sites/dido, нито на /sites, но ще се прати на /sites/stefan/pics. По подразбиране стойността на това свойство е виртуалната директория, от която първоначално е дошла бисквит­ката, но може и да се промени.

Механизъм на работа с бисквитки


За да разгледаме по-подробно механизмът на бисквитките, нека имаме примерна бисквитка с име UserID и стойност "StefanDobrev" – името на клиента. Нека датата на изтичане (свойството Expires) е 17-ти януари 2006 г., областта (свойството Domain) е devbg.org, а пътят (свойството Path) – главната виртуална директория.

Ето частта от HTTP хедъра, засягаща бисквитката, която ще се получи при клиента:



Set-Cookie: UserID=StefanDobrev; path=/; domain=devbg.org; Expires=Saturday, 17-Jan-06 00.00.01 GMT

Ако клиентският браузър е Internet Explorer, папката, в която ще се съх­рани бисквитката, е \Documents and Settings\Username\Cookies, а файлът ще е с име: username@domainname.txt. В случая, ако потребителят на системата е sdobrev, файлът ще има име sdobrev@devbg.org[1].txt. При всяка следваща заявка към този домейн и път, указан в бисквитката, браузърът е длъжен да изпрати съдържанието на бисквитката в HTTP хедъра, който също изпраща. В случая това ще е:

Cookie: UserID: StefanDobrev;

Това изпращане ще продължи, докато е валидна бисквитката. Трябва да се има предвид, че потребителят може да настрои браузъра си, така че да не приема бисквитки.

Като структура бисквитките представляват таблица от наредени тройки от типа адрес-име-стойност. Браузърът разпознава сървъра по неговия URL адрес и изпраща само тези бисквитките, предназначени за него.


Приложения на бисквитките


Както вече знаем, HTTP протоколът не може да запази състоянието на дадена заявка (той е stateless протокол). Бисквитките могат да се изпол­зват да разберем дали заявките идват от един и същи клиент.

Чрез механизма на бисквитките, сървърът може да следи потребителя и да му връща персонализирано съдържание, спрямо неговите нужди, изис­квания и интереси. Към това приложение може да причислим и възможността за проследяване поведението на потреби­те­ля и изграждане на карта на най-често посещаваните от него страници.

Друго тяхно приложение е за автоматично влизане на потребителя в даде­на уеб базирана система при неговото следващо идване. Това е възможно поради факта, че бисквитките могат да останат неограничено дълго време при клиентския браузър.

Бисквитките в .NET Framework


В .NET Framework има два класа, които предоставят достъп за работа с бисквитки.

System.Net.Cookie се използва при направата на клиентски приложения, като им предоставя функционалността да четат бисквитките, върнати от дадена уеб заявка.

System.Web.HttpCookie се използва в ASP.NET за достъп до бисквитките в уеб приложение. Чрез свойството Cookies на класовете HttpResponse и HttpRequest имаме достъп до колекция, която съдържа всички бисквитки, изпратени от сървъра или върнати от клиента.

Пример – четене от бисквитка


С този пример ще илюстрираме как може да се извлече дадена бисквитка от клиентска заявка и да се използва стойност, съхранена в нея:

HttpCookie cookie = Request.Cookies["UserID"];

if ( cookie != null )

{

LabelUsername.Text = cookie["Username"];



LabelExpires.Text = cookie.Expires;

}

Скрити полета


Скритите полета са подобни на текстовите полета, но с тази разлика, че не се показват в браузърите. Когато една страници е пратена до сървъра, съдържанието на скритите полета се праща в HTTP Form колекцията, заедно със стойностите на другите полета. Скритото поле играе ролята на държател за информация, специфична за страницата.

Скритите полета като HTML елементи


Скритите полета в HTML (hidden) имат следните атрибути:

  • name - вътрешно име на полето, служещо за идентификация

  • value - стойност, която да бъда изпратена до сървъра.

Ето един пример:


Скритите полета в .NET Framework


ASP.NET предоставя контролата HtmlInputHidden, която предлага функ­ционалността на скрито поле:

protected System.Web.UI.HtmlControls.HtmlInputHidden Hidden1;

// Аssign a value to Hidden field

Hidden1.Value = "invisible data";
// Рetrieve a value

string str = Hidden1.Value;


Особености на скритите полета


За да използвате скритите полета, трябва да употребите HTTP POST метода за пращане на уеб страници.

Също така имайте предвид, че стойността не е напълно скрита за потре­бителя. Той може да я види в сорс кода на страницата и дори да я промени. Това прави скритите полета неудачни за съхраняване на чувст­вителна и конфиденциална информация.


Параметризирани адреси (Query Strings)


Параметризираните адреси предоставят лесен, но ограничен, начин за поддържане на информация за състоянието.

Пример за параметризиран адрес


Един параметризиран URL адрес може да изглежда по следния начин:

http://asp.net/getstarted/default.aspx?tabid=61

Когато се получи заявка за getstarted/default.aspx, можем от нея лесно да извлечем кой таб е бил избран чрез следния код:

string selectedTabID = Request.Params["tabid"];

Особености при използването на параметризирани адреси


Параметрите в заявката са видими в URL адреса и на практика не осигу­ряват никаква сигурност.

Повечето браузъри поддържат до 255 знака в URL. Това значително ограничава приложението на този подход.


Технологията ViewState


ViewState (визуално състояние) е технология, чрез която може да се съхрани информация за състоянието на сървърните контроли и данни, въведени от потребителя при последователни заявки към една и съща страница. Традиционните HTML елементи са без състояние и не запазват нито данните, нито настройките от страна на клиента.

Нека си представим една уеб форма, състояща се от много на брой полета, които клиентът трябва да попълни. След попълването й трябва да валидираме въведената информация. Ако има неточности, потребителят е задължен отново да въведе цялата информация. Чрез технологията ViewState въведените от потребителя данни се запазват между заявките и не е нужно тяхното въвеждане да става отначало.


Сървърни контроли и ViewState


Благодарение на ViewState технологията, голяма част от сървърните конт­роли могат да запазват своето състояние (стойностите на отделните им свойства). Всяка динамична промяна на вътрешното състояние (промяна на свойство, свър­зване с данни и др.) на дадена сървърна контрола се запазва, за да може да бъде рендирана при клиента, когато има последо­вателни заявки към една и съща страница.

ViewState като място за съхраняване на информацията


Освен за съхраняване вътрешното състояние на сървърните контроли ViewState може да се използва и за съхраняване на информация между няколко postback извиквания. Свойството ViewState на System.Web. UI.Control (базовия клас, който наследяват всички уеб контроли, включително и Page) предоставя достъп до речникова колекция от тип име-стойност, която може да се използва за съхраняване на информация.

Пример – съхраняване и извличане на данни от ViewState


Със следващия пример ще илюстрираме как може да съхраним информа­ция във ViewState областта и след това да я извлечем от нея.

Запазване във ViewState:



ViewState["Username"] = TextBoxUsername.Text.Trim();

Извличане на вече съхранена информация от ViewState:

LabelUsername.Text = (string) ViewState["Username"];

Забележка: ако в речниковата колекция няма елемент със зададения ключ, се връща null.

Механизъм на работа на ViewState технологията


Всяка информация, добавена във ViewState (било то при динамична промяна на сървърна контрола или чрез свойството ViewState), се сериа­лизира и се изпраща на клиента под формата на скрит HTML елемент със следния вид:

value="dDw5NjU1MTU1O3Q8cDxsPFRydWU7PjtsPFZpemliaWxpd

Hk7Pj47Oz47Pm+DzsKPsEqi3imV9lUMfxhbK/Rc" />


Когато клиентът направи HTTP POST заявка към същата страница, съдър­жанието на скрития елемент се десериализира, възстановява се вътреш­ното състоя­ние на сървърните контроли и се запълва речникова колекция, достъпна чрез ViewState свойството.

Сериализацията и десе­риали­за­цията се извършват с помощта на класа LosFormatter, който е оптимизиран за работа с примитивни ти­пове, символни низове, масиви и хеш-таблици.

Както вече отбелязахме, информацията, запазена във ViewState областта, се сериализира. Това означава, че ако искаме да запазим инстанция на дефиниран от нас потребителски клас, той трябва да е маркиран с атри­бута [Serializable].

Стойността на скрития елемент __VIEWSTATE е BASE64 представяне на сериализираните контроли от формата. Въпреки че тази информация не е лесно четима, тя не е криптирана и може да бъде декодирана.





Не съхранявайте конфиденциална ин­фор­мация във ViewState!

За да се избегне фалшификация на ViewState информацията, всеки път, когато ASP.NET създава сериализи­ра­ния ViewState, автоматично към него се добавя и хеш кодът му. При следваща заявка се проверява дали данните от ViewState имат същия хеш код (т.е. дали не са променени). Тази опция може да се изключи, като в директивата @Page зададем стойност false на атрибута EnableViewStateMac.

Поддържане на ViewState


Ако дадена уеб страница съдържа множество контроли, цялостният раз­мер на ViewState областта може да нарасне драстично, което от своя страна увеличава размера на страницата, която се изпраща към клиента. В подобни случаи може да ограничим използването на ViewState само върху контролите, които се нуждаят от него. Например за контрола от тип Label, която има зададено свойство Text в aspx страницата и знаем, че това и останалите й свойства няма да се променят, е разумно да изключим ViewState-a. Това може да стане така:

EnableViewState="False" />



Изключването на ViewState може да стане и на ниво страница:

<%@ Page EnableViewState="False" %>

Това е удобно, ако искаме да разрешим използването на ViewState само за определени контроли.

Запазване на ViewState в Session обекта


Когато обемът на информацията, съхранена във ViewState, нарасне, цялостният размер на HTML страницата, изпратена към клиента, също нараства. Това може да доведе до изпращане на страници с размер от около 0.5 – 1 МB, което не е препоръчително.

Един сценарий, в който е удачно да поддържаме малък ViewState е, когато разработваме приложения за мобилни клиенти. В тези ситуации е добре да го съхраняваме на друго място, като избегнем неговото рендиране при клиента и в същото време запазим състоянието. В примера ще покажем как това може да стане в Session обекта. За целта ще препокрием два от виртуалните методи на класа System.Web.UI.Page: LoadPageStateFrom PersistenceMedium() и SavePageStateToPersistenceMedium(…). Ето и кода, който осъществява това:



protected override object LoadPageStateFromPersistenceMedium()

{

return Session["ViewState"];



}
protected override void SavePageStateToPersistenceMedium(

object viewState)

{

Session["ViewState"] = viewState;



}

С този пример демонстрирахме как можем да контролираме механизма на записване и зареждане на ViewState информацията. Може да се използват и произвол­ни други места за съхранение: бази от данни, файлове, соб­ствени скрити полета и др.

Състояние на приложението


В рамките на ASP.NET приложение информация да бъде споделяна чрез класа HttpApplicationState (достъпван най-често чрез Application свойството на HttpContext обекта). Този клас ни предоставя речникова колекция, където можем да съхраняваме обекти и скаларни стойности, свързани с множество уеб заявки и клиенти.

При първата заявка към URL ресурс от виртуалната директория на ASP.NET приложение се създава инстанция на класа HttpApplicationState. По време на всяка заявка всички модули HttpModule и обработчици HttpHandlers (в това число ASP.NET страници­те), имат достъп тази инстанция чрез свойството Application на HttpContext обекта.

За поддръжка на състояние на ниво приложение ASP.NET ни предоставя:


  • Речникова колекция, достъпна за всички обработчици на заявки в приложението.

  • Лесен механизъм за синхронизация до променливите на състоянието.

  • Сигурност, че други ASP.NET приложения не могат да достъпват и променят състоянието на нашето приложението.

Използване на състоянието на приложението


Променливите на състоянието на Application обекта, са на практика глобални за ASP.NET приложение. Затова при вземане на решение дали да ги използваме, трябва да имаме предвид следните фактори:

  • Памет - паметта не се освобождава докато променливата не бъде заменена или премахната. В някои случаи е лоша идея да се държат постоянно в паметта рядко достъпвани данни с голям размер.

  • Нишкова безопасност – ако обектите, които съхраняваме, не са нишково обезопасени, то трябва да положим допълнителни усилия за синхронизиране на достъпа до тях.

  • Скалируемост – при използване на заключвания за осигуряване на нишкова безопасност, операционната система блокира другите рабо­тещите нишки, чакащи за ресурса. Това може да доведе до значи­телно падане на производителността на приложението.

  • Възстановяване на данните – по време на изпълнение на прило­жението, домейнът на приложението може да бъде унищожен във всеки момент (в резултат на срив, промени в кода, планирано рестар­тиране на процеса, и др.). В такъв случай данните за състоя­нието на приложението ще бъдат загубени. Ако такова поведение е неже­лателно, трябва да предприемем допълнително стъпки за решаване на проблема.

  • Състоянието на приложението не е споделено в рамките на уеб ферма (приложение, изпълнявано на няколко сървъра) или уеб градина (приложение, изпълнявано на няколко процеса на един сър­вър). Променливите, съхранявани в състоянието на приложе­нието, са глобални само в рамките на един процес.

Въпреки тези особености, променливите на ниво приложение могат да бъдат много полезни. В тях можем да пазим рядко извличана, но често достъпвана информация от бази от данни и така да подобрим значително скоростта на обработка на заявките. От друга страна, този ефект можем да бъде постигнат и с механизмите за кеширане в ASP.NET, които ще разгледаме по-късно.

Колекции за състоянието на приложението


Класът HttpApplicationState предоставя две колекции: Contents и StaticObjects.

Колекцията Contents дава достъп до променливите добавени по следния начин:



Application["AppStartTime"] = DateTime.Now;

Можем изрично да използваме свойството Contents:

Application.Contents["AppStartTime"] = DateTime.Now;

Колекцията StaticObjects предоставя достъп до променливите, дефини­рани чрез тагове във файла Global.asax:

ID="MyInfo" PROGID="MSWC.MYINFO">





Можем да използваме така дефинираните обекти по следния начин:




Сподели с приятели:
1   ...   25   26   27   28   29   30   31   32   33




©obuch.info 2024
отнасят до администрацията

    Начална страница