Body zdarma Java týden
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde
Pouze tento týden sleva až 80 % na Java e-learning!

Diskuze: MVC Session životnost na serveru

Aktivity (4)
Avatar
Horas
Člen
Avatar
Horas:19. srpna 8:38

Používám Session pro udržení o přihlášení a obsahu košíku ve web aplikaci. Na lokálním spuštění mi to vše funguje, ale jak aplikaci nahraju na webhosting, Session fungují jen chvíli a poté svévolně ztrácí informaci.

Zkusil jsem: Při různém testování na webhositngu mí přišlo, že vše ovlivňuje množství datového přenosu. Tedy, že čím více dat přenáším, tím dříve Session ztratí niformaci. Ale to je jen moje domněnka.

Chci docílit: Nevím jak udržet informaci v Session na potřebnou dobu (na webhostingu). Zkrátka, aby vše fungovalo jako na lokále. Může mi to někdo vysvětlit? Díky předem

 
Odpovědět 19. srpna 8:38
Avatar
Daniel Vítek
Tým ITnetwork
Avatar
Odpovídá na Horas
Daniel Vítek:19. srpna 9:06

Životnost session lze ovlivnit přes nastavení php, konkrétně session.gc_max­lifetime a session.cooki­e_lifetime.

Zkus si zkontrolovat, jestli tam nejsou nějaké nestandardní hodnoty, default je 1440 a 0.

Nahoru Odpovědět 19. srpna 9:06
Na síti působím už pěknou řádku let. Pokud budeš něco potřebovat, písni mi, pokusím se ti poradit :)
Avatar
Horas
Člen
Avatar
Odpovídá na Daniel Vítek
Horas:19. srpna 9:24

Mám to napsané v C# a jak jsem psal, na lokále ta samá aplikace funguje.

Editováno 19. srpna 9:25
 
Nahoru Odpovědět 19. srpna 9:24
Avatar
Ghst
Člen
Avatar
Odpovídá na Horas
Ghst:19. srpna 9:51

Jak píše Dan, zkontroluj nastavení ISS položku časový limit relace. Na lokále pracuješ s jiným serverem, který může mít jiné nastavení než ten webhostingový.

 
Nahoru Odpovědět 19. srpna 9:51
Avatar
zelvicek
Člen
Avatar
Odpovídá na Horas
zelvicek:19. srpna 10:20

Je třeba si uvědomit, jak se Session data ukládají. Obecně: pro uložení dat je potřeba místo (RAM/disk/DB/...). Pokud ukládáš mnoho dat, potřebuješ mnoho místa.
Nepíšeš, jak Sessions ukládáš (In-process memory nebo nějaké perma úložiště). Předpokládám, že in-process memory.
Může docházet k tomu, že pokud požaduješ příliš RAM, IIS recykluje pooly - tzn. shodí starou aplikaci/process a nahodí novou.
Taky nepíšeš, zda se session "ztratí" vždy po stejné době nebo nahodile (z pohledu času).
Další věcí je LoadBalancing - pokud aplikaci provozuješ na více serverech, musíš sessions sdílet. Je asi jasné, že si servery navzájem do pamětí nevidí.

OT: pro veřejný web bych se sessions vyhnul. Vhodná náhrada může být JWT.

 
Nahoru Odpovědět 19. srpna 10:20
Avatar
Odpovídá na Horas
don.jarducius:19. srpna 10:42

Jak píše @zelvicek, server jednou za stanovený čas nebo po určitém eventu recykluje aplikační pool.
In-process memory na webhostingu vůbec nepoužívej. Ideální je pro tebe uložiště na SQLServer, nebo StateSterver. Informace v session pak přežijí restart aplikace i serveru a dají se sdílet i v rámci více serverů.

Nastavuje se ve Web.config:

<system.web>
    <sessionState mode=" SQLServer" allowCustomSqlDatabase="true" sqlConnectionString="tvůj connection string" />
</system.web>

Má to ale malý háček, informace, které do session ukládáš se musejí dát serializovat nebo musejí být označeny atributem Serializable.

Tady máš odkaz na návod jak to nastavit pro ukládání do SQL DB

Nahoru Odpovědět 19. srpna 10:42
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Daniel Vítek
Tým ITnetwork
Avatar
Odpovídá na Horas
Daniel Vítek:19. srpna 11:21

Uhh promiň, vůbec mi nedocvaklo podívat se na kategorii :-X automaticky jsem bral PHPčko

Nahoru Odpovědět 19. srpna 11:21
Na síti působím už pěknou řádku let. Pokud budeš něco potřebovat, písni mi, pokusím se ti poradit :)
Avatar
Horas
Člen
Avatar
Odpovídá na don.jarducius
Horas:19. srpna 15:50

SQLServer uložiště se mi povedlo rozběhnout na lokále, super, ale nevím jak nakonfigurovat SQL server na webhostingu. Systémovou databázi tempdb tam sice mají, ale neobsahuje tabulky ASPStateTempAp­plications, ASPStateTempSes­sions. Zkrátka nevím jak tam dostat ty potřebné věci. Mužeš mi poradit.

 
Nahoru Odpovědět 19. srpna 15:50
Avatar
Odpovídá na Horas
don.jarducius:20. srpna 10:29

Ty 2 tabulky nemusí být v tempDB, můžeš je mít i ve své DB, . Důležitá je i údržba tabulky ASPStateTempSes­sions, dokáže docela rychle nabobtnat. Stačí v ní mazat exspirované řádky - sessiony (where [Expires] < getdate())

Nahoru Odpovědět 20. srpna 10:29
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Horas
Člen
Avatar
Horas:21. srpna 9:52

Tak už jsem to rozběhl, co se týče ukládání Session na SQL všude. Při změně InProc na SQLServer mi ale přestávají fungovat AJAX. Volám jim ActionResult v Controlleru a až po

...
Session["cart"] = cart;
return Json(cart, JsonRequestBehavior.AllowGet);

to jede stejně. Verze InProc to vrátí zpět do AJAX a dá se s tím dál pracovat, ale verze SQLServer se do AJAX už nevrátí.
Zkoušel jsem serializovat třídy, s kterými to souvisí, ale nic se nezměnilo.

 
Nahoru Odpovědět 21. srpna 9:52
Avatar
Odpovídá na Horas
don.jarducius:21. srpna 10:42

Session s tím souviset nebude, co ti přiletí zpět do prohlížeče v odpovědi na ten ajax?
Nejsou jinak pojmenovaný pole, velikost písmen, vím že si json serializer v MVC dokáže dělat s názvy co chce :)

Nahoru Odpovědět 21. srpna 10:42
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Horas
Člen
Avatar
Horas:21. srpna 12:06

Tak chybu mám v ActionResult v tom zápisu do Session. Jakmile vyřadím Session["cart"]=car­t, pak AJAX funguje normálně. Asi úplně dobře nevím jak a co serializovat. Co všechno musím označit atributem Serializable?

 
Nahoru Odpovědět 21. srpna 12:06
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Horas
Člen
Avatar
Odpovídá na don.jarducius
Horas:21. srpna 15:00

Problém je v tom, že do Session ukládám něco takového:

List<EshopItem> cart = new List<EshopItem>();

cart.Add(new EshopItem { Product = productModel.find(id), Quantity = quantity });
Session["cart"] = cart;

Všechny třídy, kterých se to dotklo jsem označil [Serializable()], ale ničemu to nepomohlo.

 
Nahoru Odpovědět 21. srpna 15:00
Avatar
Odpovídá na Horas
don.jarducius:21. srpna 15:07

Vyhazuje to výjimku, nebo pak zdánlivě v sessioně nic není?

Nahoru Odpovědět 21. srpna 15:07
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Horas
Člen
Avatar
Odpovídá na don.jarducius
Horas:21. srpna 15:10

V Session je vše uloženo, na SQL se to taky tváří, že něco zapsal, ale jak jsem psal dříve, nevrátí mi příkaz:

return Json(cart, JsonRequestBehavior.AllowGet);

hodnoty zpátky do pohledu.

 
Nahoru Odpovědět 21. srpna 15:10
Avatar
Odpovídá na Horas
don.jarducius:21. srpna 15:17

Ok, v konzoli prohlížeče v sekci síť sedí odpověď serveru s očekáváním? Nevidím totiž žádný důvod proč by to nemělo vrátit data...

Nahoru Odpovědět 21. srpna 15:17
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Horas
Člen
Avatar
Odpovídá na don.jarducius
Horas:22. srpna 12:41

Právě v té odpovědi mám chybu. Pokud v controlleru nepoužívám ukládání do Session mám:

Status Code: 200 OK
Response Headers
Content-Type: applications/json; cahrset=utf--8

Jakmile odblokuju ukládání do Session:

Status Code: 500 Internal Server Error
Response Headers
Content-Type: text/html; cahrset=utf--8

Nevím jak se vypořádat s tím Content -Type, což je jediný rozdíl.

 
Nahoru Odpovědět 22. srpna 12:41
Avatar
Horas
Člen
Avatar
Horas:22. srpna 13:50

Ještě mi to píše:
Stav relace nelze serializovat. V režimu StateServer a SQLServer bude technologie ASP.NET serializovat objekty stavu relace, a v důsledku toho nejsou objekty bez možnosti serializace nebo objekty MarshalByRef povoleny. Stejné omezení platí v případě, že je podobná serializace provedena vlastním úložištěm stavu relace v režimu Custom.

[Serializatio­nException: Typ System.Data.En­tity.DbContext v sestavení EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c56­1934e089 není označen jako serializovatelný.]

 
Nahoru Odpovědět 22. srpna 13:50
Avatar
don.jarducius:22. srpna 14:35

Jasně… To znamená že nemáš všechny své vlastní třidy, které se ukládají do Sessiony, označené atributem [Serializable]

Projdi všechny třídy které se mohou dostat do session zda mají atribut [Serializable], resp. všechny své třídy/modely opatři atributem [Serializable].

List<EshopItem> cart = new List<EshopItem>();

cart.Add(new EshopItem { Product = productModel.find(id), Quantity = quantity });
Session["cart"] = cart;
Nahoru Odpovědět 22. srpna 14:35
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
Horas
Člen
Avatar
Odpovídá na don.jarducius
Horas:22. srpna 17:08

Označil jsem třídy/modely [Serializable], ale chyba přetrvávala.

Tak jsem zkusil testovat od základů co projde. Nakonec jsem dospěl k vytvoření třídy stejné jako EshopItem(stejné vlastnosti, bez metod) a s ní to prošlo. Takže problém je někde v těch metodách.

 
Nahoru Odpovědět 22. srpna 17:08
Avatar
Odpovídá na Horas
don.jarducius:22. srpna 20:18

A všechny vlastní třídy, které jsou jako property ve třídě EshopItem jsou taky označeny Serializable?

Nahoru Odpovědět 22. srpna 20:18
Ten kdo nechce hledá důvod, ten kdo chce hledá způsob
Avatar
zelvicek
Člen
Avatar
Odpovídá na Horas
zelvicek:22. srpna 21:04

Konečně jsme se někam pohli - a stačilo uvést konkrétní chybu.
Předpokládám, že

productModel.find(id)

načítá data z DB pomocí EF.
Zkus si vypsat

productModel.find(id).GetType().AssemblyQualifiedName

. Myslím, že budeš překvapen.

 
Nahoru Odpovědět 22. srpna 21:04
Avatar
Horas
Člen
Avatar
Odpovídá na don.jarducius
Horas:23. srpna 8:57

Problém vyřešen, všechny vlastní třídy byly označeny Serializable, ale celé to blokoval řádek v rámci třídy EshopItem pro DBContext, což nebylo nutné tam mít.

private EshopDBEntities db = new EshopDBEntities();

Třída EshopDBEntities je public partial a měl jsem ji také označenou Serializable, ale přesto to nefungovalo. Nevím jestli by šlo její serializování vyřešit nějak jinak, ale já ji inicializuji v controlleru a do metody ve třídě EshopItem ji předávám jako parametr. Každopádně díky za pomoc.

Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět 23. srpna 8:57
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 23 zpráv z 23.