ASP.NET Managing State
Roberto Brunetti
[email protected]
Blog: blogs.devleap.com/rob.rss
http://www.DevLeap.it
Chi siamo
• www.DevLeap.it
• Un gruppo di 5 persone con tanta voglia di
•
•
•
•
•
Studiare a fondo le tecnologie
Capire il “behind the scenes”
Implementare soluzioni reali
Confrontarsi con le problematiche reali
Sperimentare nuove idee
http://www.DevLeap.it
Cosa Facciamo
•
•
•
•
•
•
•
•
•
Sviluppo
Corsi
Conferenze
Seminari
Mentoring
Analisi e disegno di progetto
Auditing su realizzazioni proprie o di terze parti
Valutazione skill risorse umane
Non facciamo sviluppo direttamente
• (Supporto telefonico/via email a contorno di altri servizi:
mentoring)
• Definizione di percorsi di crescita per team di sviluppo
http://www.DevLeap.it
Html e Http
La dura verità
http://www.DevLeap.it
Request/Response Http
Server
Client
IIS/Apache
Richiesta HTTP
default.htm
Risposta HTTP
http://www.DevLeap.it
ASP: flusso dell’applicazione
Server
Client
IIS
http://www.dcc.com/equipment/catalog_type.asp?
ProductType=rock+shoes
Richiesta HTTP
Active Server Pages
engine
Risposta HTTP
Esecuzione
JScript
VB
/ C#
ADO.NET
Recupero risultati
http://www.DevLeap.it
default.aspx
Stateless
• Ogni richiesta è a se stante
• Non esistono informazioni di stato in Http
• Per ogni richiesta dobbiamo preoccuparci
di inviare il contenuto
• Ad esempio riempire i campi di un form
con le informazioni digitate dall’utente
http://www.DevLeap.it
Stateless
• Ripresentare le informazioni digitate
<INPUT
TYPE=“TEXT”
NAME=“txtNome”
VALUE=<%=Request.QueryString(“txtNome”)
%>
>
http://www.DevLeap.it
ASP.NET Web Form
<FORM action=“NomeRisorsa”
METHOD=“POST”>
<INPUT TYPE=“Text” ID=“txtNome”
runat=“server”>
<INPUT TYPE=“Text” ID=“txtCognome”
runst=“server”>
<INPUT TYPE=“Submit”>
</FORM>
• I controlli mantengono lo stato
http://www.DevLeap.it
Mantengono lo stato ?
• I controlli server mantengono le proprietà
impostate fra round-trip
• Tramite un campo hidden
• __VIEWSTATE
• Pro
• Meno plumbing
• Meno roundtrip verso i dati
• Contro
• __VIEWSTATE occupa banda
• E’ disabilitabile
http://www.DevLeap.it
Demo 10
• ViewState
• View Source
• Modifica attributo al click
• Azzera: Cambia colore pulsante
• Disable su Controllo
• Non tiene il bgcolor
• Disable su Pagina
• Non tiene il bgcolor
http://www.DevLeap.it
Gestione dello stato
Burocrazia ?
Intro/Real
http://www.DevLeap.it
Manage State ?
• Il Web è stateless
• Mantenere lo stato delle informazioni
• Valori
• Variabili
• Proprietà
• Server-Side per riutilizzarli fra richieste
diverse
• Sulla stessa pagina
• Sull’intera applicazione
http://www.DevLeap.it
Manage State
• Server Side
•
•
•
•
Web.Config
Application
Session (se cookie andrebbe dopo)
Caching
• Client/Server Side
•
•
•
•
Cookie
Hidden Field
QueryString
ViewState
http://www.DevLeap.it
Web.Config
• Può contenere valori Custom
• Connection String
• Informazioni statiche che prima si mettevano
in Application o su file esterni
• <appSettings>
• <add key=“cString” value=“.....” />
• </appSettings>
• Nel codice
• Using/Imports System.Configuration
• strConn = Configuration.AppSettings(“DSN”)
http://www.DevLeap.it
Occhio al Publish
• Differenziare Test / Produzione
•
•
•
•
•
Connessioni al DB
Email routing
Log
Security
Etc
• Exclude / Include da VS.NET
http://www.DevLeap.it
Web.Config
• Quando viene letto
• Alla partenza dell’applicazione
• Quando è necessario ricompilare
• Dove viene mantenuto
• HashTable nell’HttpContext
• Come si accorge dei cambiamenti
• Viene calcolato l’hash di
• CreationTime + LastWriteTime + Lenght
• E memorizzato in un file esterno nella directory di
compilazione
• Ad ogni richiesta viene fatta la verifica del valore
dell’hash
• Se non quadra viene riletto
http://www.DevLeap.it
Application
• Classe HttpApplicationState
• Oggetto Application
• Esposto come proprietà di
• HttpContext e Page
• Memoria condivisa per tutta l’applicazione
• Indipendente dall’utente
• Accesso tramite Nome/Valore
• Non usarla per dati temporanei
• Difficile impostare una scadenza
• Da non confondere con la classe HttpApplication
esposta come ApplicationInstance che
rappresenta l’intera applicazione ASP.NET e non
un’area di memoria
http://www.DevLeap.it
Session Session...
• In ASP 1/2/3 le session
• Necessitano del supporto dei cookie sul client
• Sono single-machine e non adatte a
configurazione di load-balancing
• Consumano molta RAM
• In ASP.NET le session
•
•
•
•
Possono lavorare come prima oppure
Non necessitare dei cookie
Essere multi-machine
Appoggiarsi su DB o su uno State Server
http://www.DevLeap.it
Session
• Classe HttpSessionState
• Oggetto Session
• Esposto come proprietà di
• HttpContext e Page
• Memoria condivisa per tutta l’applicazione
• Dipendente dall’utente
• Accesso tramite Nome/Valore
• Non usarla per dati temporanei
• Difficile impostare una scadenza
• Implementata dal modulo
System.Web.SessionState.SessionStateModule
http://www.DevLeap.it
Cos’è
Browser
Browser
Server
Cookie
URL Sess
Session
Cookie
Session
URL Sess
ASP.NET worker thread 1
HttpRuntime
Class
Modulo X
Session
HTTP Handler
Pagina1.aspx
ASP.NET worker thread 2
HttpRuntime
Class
Modulo X
Session
ASPNET_WP.EXE
http://www.DevLeap.it
HTTP Handler
Pagina2.aspx
Come si usa
• Session(“nome”) = Valore
• Response.Write(Session(“nome”))
• Non occorre definire le varibili
• Come nella vecchia versione
• Ma occhio a controllarne l’esistenza prima di
utilizzarne un valore
• Oppure valorizzare tutte la var nel
Session_OnStart
http://www.DevLeap.it
Configurazioni possibili
<sessionState
mode="Off|Inproc|StateServer|SQLServer"
cookieless="true|false"
timeout="number of minutes"
stateConnectionString="tcpip=server:port"
sqlConnectionString="sql connection string"
/>
• Off se non si usa
http://www.DevLeap.it
Session senza Cookie
<sessionState cookieless=“true" />
• Non necessita di cookie abilitati sul client
• Il cookie viene copiato nei vari Url linkati dalla
pagina
• Http://xxx.com/3463287462764/pagina.aspx
• Utilizzabile in tutte le modalità
• Session.Mode
• Gestiti dal filtro ISAPI ASPNET_FILTER.DLL
http://www.DevLeap.it
In-process Session
ASPNET_WP
Browser
Browser
Cookie
URL Sess
Session
Cookie
Session
URL Sess
<sessionState mode=“InProc” cookieless="true|false" />
• Più veloce
• Singolo Server – No Load Balancing
• Se ASPNET_WP crasha – Addio Session
http://www.DevLeap.it
Browser
Browser
Cookie
URL Sess
Cookie
URL Sess
ASPNET_WP
ASPNET_STATE
SERVER 3
SERVER 1
Session
Session
Browser
Cookie
URL Sess
ASPNET_WP
SERVER 2
Session
<sessionState mode=“StateServer” cookieless="true|false"
stateConnectionString="tcpip=server3:42424" />
• ASPNET_STATE Può girare anche sullo stesso server
• Se ASPNET_WP crasha – Le Session sopravvivono
• Più lento di InProcess – Più veloce di SQL Server Session
• Load Balancing
• Se crasha ASPNET_STATE – Addio Sessioni di tutti i server
http://www.DevLeap.it
Browser
Browser
Browser
Cookie
URL Sess
Cookie
URL Sess
Cookie
URL Sess
ASPNET_WP
Sql Server
o
Sql Cluster
SERVER 1
Session
ASPNET_WP
SERVER 2
Session
Session
<sessionState mode=“SQLServer” cookieless="true|false"
sqlConnectionString=“ConnString” />
• SQL può girare anche sullo stesso server
• Se ASPNET_WP crasha – Le Session sopravvivono
• Metodo più lento ma più sicuro (se in cluster)
• Load Balancing
http://www.DevLeap.it
SQL Server Session
• %WinDir%\Microsoft.NET\Framework\vxxxx\I
nstallSQLState.sql
• Per creare Database e Stored Procedure
• DataBase: ASPState
• SP: Insert, Get, Update
• I dati vengono appoggiati al TEMPDB
• Al Restart di SQL Server le Session vengono perse
• Possiamo modificare InstallSQLState per creare e
appoggiare i dati su un altro DB
• Nella 1.1 InstallPersistSQLState.sql
http://www.DevLeap.it
Per avere un idea
1400
Requests/Sec (2P Server)
1200
1000
800
600
400
200
0
ASP.NET InProc
ASP.NET State Store ASP.NET SQL Store
http://www.DevLeap.it
HttpHandler e HttpModule
ASP.NET worker thread 1
HttpRuntime
Class
Modulo 1
Modulo 2
PageHandler
Pagina1.aspx
ASP.NET worker thread 2
HttpRuntime
Class
Modulo 1
Modulo 2
ASPNET_WP.EXE
http://www.DevLeap.it
PageHandler
Pagina2.aspx
HttpHandler e HttpModule
ASP.NET worker thread 1
HttpRuntime
Class
Authent
Session
PageHandler
Pagina1.aspx
ASP.NET worker thread 2
HttpRuntime
Class
Authent
ASPNET_WP.EXE
http://www.DevLeap.it
PageHandler
Pagina2.aspx
SessionStateModule
• Dopo aver letto la configurazione relativa
alle sessioni
• Si abbona all’evento AcquireRequestState,
ReleaseRequestState e EndRequest.
• Durante la gestione dell’
AcquireRequestState recupera il SessionID
ed i valori da inserire nell’oggetto Session
http://www.DevLeap.it
Session Conclusione
• Non abbiamo più i problemi di ASP 3.0
• Nessun problema di COM Affinity
• Load Balancing consentito
• Detto questo, non usatele se non ne avete bisogno
• Togliere l’HttpModule da Machine.Config
• Oppure <page enableSessionState=“false” />
• Togliere il modulo dal Web.Config
• <httpModules>
• <remove name=“Session” />
• </httpModules>
• Oppure <page enableSessionState=“false” />
• Disabilitare le session sulle pagine che non le utilizzano
• @Page EnableSessionState=“false”
• Se una pagina legge solamente i valori senza scriverli
• @Page EnableSessionState=“readonly”
http://www.DevLeap.it
Cookie
• Namespace System.Web
• Semplice
• x = new HttpCookie(name,value)
• Response.AppendCookie(x)
• If Request.Cookies(name) = Null / null
• Stringa = Request.Cookies(name)
• Da non confondere con
• System.Net.Cookie
http://www.DevLeap.it
Cookie multivalue
• x = new HttpCookie(name)
• x.Values.Add(“nome”, “valore”)
• Response.AppendCookie(x)
• If Request.Cookies(name) = Null / null
• Stringa =
Request.Cookies(name).Values(“nome”)
• Usare il meno possibile gli oggetti ->
http://www.DevLeap.it
Passare da variabile locale
• x = new HttpCookie(name)
• x.Values.Add(“nome”, “valore”)
• Response.AppendCookie(x)
• HttpCookie x = Request.Cookies(name)
• If x = Null / null
• Stringa =x.Values(“nome”)
http://www.DevLeap.it
Cookie Member
•
Domain
•
Expires
• Dominio da associare al cookie
• DateTime per la scadenza.
• HasKeys
• True se ha subkeys
• Item
• Shortcut per HttpCookie.Values[ key ]
• Per compatibilità con ASP 3.0
• Name
• Legge/Imposta il nome del cookie
• Path
• Path da associare al cookie
• Secure
• Legge/Imposta l’invio sicuro (su Https)
• Value
• Valore del cookie single-value
• Values
• Collection nome/valore contenuto nel cookie
http://www.DevLeap.it
Cookie Warnings
• Usare Https per
• Criptare il traffico di username e password
• Criptare i cookie persistenti su disco
• RedirectFromLoginPage(..., True)
• Su tutto il sito per evitare che il cookie di login
passi in chiaro
• Occhio ai tag IMG e HREF
• Negare l’accesso Http a tutte le parti protette per essere
sicuri
• Se il sito ha una parte protetta Https si deve
stare attenti
• Path=qualcosa per inviarlo solo a tali directory
• Altrimenti viene inviato anche per le richieste http
verso le altre sezioni del sito
http://www.DevLeap.it
Manage State
• Per Roundtrip su stessa pagina
• Campi Hidden
• Li conosciamo
• ViewState
http://www.DevLeap.it
VIEWSTATE
•
•
•
•
Proprietà della classe Control
Contiene le informazioni di stato dei controlli
Dictionary della classe State
Si trasforma in un campo hidden
• Dopo Base64 Encoding
• __VIEWSTATE
• Per default è null o empty
• I valori possono essere letti e scritti anche da
codice
• ViewState[“xxx”] = “ABC”
http://www.DevLeap.it
ViewState nella sequenza eventi
Page/
Control
Init
PreRender
VIEWSTATE
Save
VIEWSTATE
Load
Events:
_Change
_Click
Page_Load
Render
http://www.DevLeap.it
Update
input field
Validation
Dispose
ViewState
•
•
•
•
•
LoadViewState
SaveViewState
Metodi implementati dalla classe base
Sono Overridable
Filtri per i valori più comuni
• String, Int, Boolean, Array, ArrayList,
HashTable
• Possiamo scriverci filtri per nostri tipi
• Che devono essere serializzati
http://www.DevLeap.it
ViewState VS ...
• Hidden
• E’ un campo hidden
• Cookie
• Non necessita di cookie abilitati
• Il viewstate serve per singola pagina
• Session
• Le session sono pesanti, soprattutto su DB
• Il viewstate serve per singola pagina
• Application
• Non è specifica per utenti
• Il viewstate serve per singola pagina
• Cache
• Il viewstate serve per singola pagina
• La Cache è temporanea
• La vediamo fra un attimo
http://www.DevLeap.it
ViewState Property/Method
• EnableViewState
• Per pagina o controllo
• IsTrackingViewState
• True mentre il controllo scrive nella StateBag
• ViewStateIgnoreCase
•
•
•
•
• True = StateBag Case insensitive
HasChildViewState
ClearChildViewState
Load/Save
TrackViewState
• Monitorizza le modifiche al viewstate per salvarle nella
StateBag
http://www.DevLeap.it
ViewState Sicuro
• Default
• Base64 Encoding: Come se fosse in chiaro 
• <pages enableViewStateMac="true“
• Disabilitabile anche da Machine / Web.Config
• Non da codice
• Controllo integrità
• Machine.Config machineKey per algoritmo di hash
• SHA1
• MD5
• Cripting
• Machine.Config machineKey
• 3DES
http://www.DevLeap.it
Cripting
Response
Request
SaveViewState
Client
“VIEWSTATE”
“ETATSWEIV”
decriptionKey
decriptionKey
“ETATSWEIV”
Client
“VIEWSTATE”
LoadViewState
http://www.DevLeap.it
Controllo Integrità
Response
VIEW
Request
validationKey
Hash
VIEW
Client
Hash
VIEW
Hash
VIEW
validationKey
Hash
Hash
http://www.DevLeap.it
=
Hash
Hash e Cript
• Machine.Config
• validationKey
• Per controllo signature
• decriptionKey
• Per chiave di criptaggio
• Se single-server
• autogenerate va benissimo
• Se Load-Balancing
• Devono essere uguali in tutti i machine.config
dei server in questione
http://www.DevLeap.it
ViewState Performance
• Server
• Disabilitabile per pagina o controllo
• @Page EnableViewState = “false” ...
• <asp:TextBox EnableViewState = “false” ...
• Disabilitabile da Web.Config
• <pages enableViewState="true“
• Disabilitabile da Machine.Config
• <pages enableViewState="true“
• Da Codice
• Page.EnableViewState = false
• Control.EnableViewState = false
http://www.DevLeap.it
ViewState Performance
• Ancora Server
• Usare solo i 6 filtri di default
• Oggetti custom serializzabili
• Molto alto il costo di serializzazione
• Non consuma risorse server (RAM, DISCO)
• Non criptarlo per maggiori performance
• Client
• E’ un campo hidden
• Se troppo grande lentezza nel passaggio dei dati
• Tracing per controllare il peso dei singoli controlli
http://www.DevLeap.it
Caching
Occhio alla pronuncia
Intro
http://www.DevLeap.it
Caching
• Il miglior modo di ottimizzare il codice è
• Non eseguirlo !!!
• Se i dati non cambiano in un arco di
tempo perchè rieseguire le query ?
• Il codice statico è molto più veloce del
codice dinamico
• Torniamo a FrontPage  
• Mai !  magari a DreamWeaver
http://www.DevLeap.it
Caching di Pagine e Controlli
• Implementato da
System.Web.Caching.OutputCacheModule
Cache
ASP.NET worker thread 1
HttpRuntime
Class
OutputCache
Session
HTTP Handler
Pagina1.aspx
ASP.NET worker thread 2
HttpRuntime
Class
OutputCache
ASPNET_WP.EXE
http://www.DevLeap.it
HTTP Handler
Pagina2.aspx
Page Output Caching
• La pagina viene eseguita la prima volta
• Viene cachata
• E recuperata dalla cache per le richieste
successive
• Direttiva di cache per la pagina
• <%@ OutputCache Duration=“10”
VaryByParams=“none” %>
• Oppure da codice
• Response.Cache.SetExpires(DateTime.Now.Ad
dSeconds(10))
http://www.DevLeap.it
Cache Location
• <%@OutputCache Location= “ “ %>
•
•
•
•
•
Server
Client
Downstream
Public
None
• Da codice
• Response.Cache.SetCacheability
• HttpCacheability.Server
• HttpCacheability.Client
• ....
http://www.DevLeap.it
Direttiva OutputCache
• La pagina potrebbe essere diversa in base
al QueryString o alla POST
• VaryByParam
• Cacha n copie della pagina in base ai
parametri HTTP GET / POST
• Indicare i parametri da considerare separati
da “;”
• Supporta * (per tutti i parametri)
• Esempio VaryByParam=“TipoCorso; SedeCorso”
• Parametro obbligatorio
• Impostarlo a ‘none’
http://www.DevLeap.it
Oppure OutputCache
• VaryByHeader
• Cache le pagine in base agli header HTTP
• Sempre stringa con “;”
• Esempio LOGON_USER
• VaryByCustom
• Su tipo di browser – ‘Browser’
• Estensibile
• Sempre stringa “;”
http://www.DevLeap.it
VaryByCustom Esempio
• VaryByCustom=“Preferenze”
• VB
Public Overrides Function GetVaryByCustomString(context as HttpContext, arg as String)
as String
Select Case arg
Case “Preferenze”
Return(“Preferenze=“ & Request.Cookies(“Pref”)
Case ...
End Select
End Function
• C#
public override string GetVaryByCustomString(HttpContext context, string arg ) {
switch (arg) {
case “Preferenze”
Return(“Preferenze=“ & Request.Cookies(“Pref”);
case ...
}
}
http://www.DevLeap.it
Partial Caching
• Non è detto che si voglia sempre cachare
tutta la pagina
• Sensato cachare solo le parti comuni
• Partial Page Caching
•
•
•
•
•
Consente di cachare User Control
Ognuno con criteri diversi
La sintassi è identica
Attributo VaryByControl
Estensibile con Proprietà
http://www.DevLeap.it
Caching API
Occhio alla pronuncia
Intro
http://www.DevLeap.it
Cache API
• Classe Cache
• Namespace System.Web.Caching
• Oggetto Cache
• Esposto da Page.Response
• Memoria condivisa per tutta l’applicazione
•
•
•
•
Indipendente dall’utente
Accesso tramite Nome/Valore
Usarla per dati temporanei
Gli item usati “poco” vengono rimossi
• Supporta la notifica di rimozione tramite il
Delegate CacheItemRemovedCallBack
http://www.DevLeap.it
Un esempio
• Cache.Add o Cache.Insert
(
Nome
Valore
Dependency
Time
TimeSpan
Priority
PriorityDecay
CallBack
)
http://www.DevLeap.it
Cache Dependency
• Dependency da file
• New CacheDependency
• Da File/Directory (Array di File o Directory)
• Iniziare ad un DateTime specifico
• Da un altro elemento in cache
• Da un array di elementi in cache
• Da un’altra dependency
• Mshelp://MS.NETFrameworkSDK/cpref/html/f
rlrfSystemWebCachingCacheDependencyCl
assctorTopic.htm
http://www.DevLeap.it
Cache RemovedCallBack
private static CacheItemRemovedCallback onRimoz =null;
onRimoz = new
CacheItemRemovedCallBack(this.RemovedCallBack);
Cache.Insert(“xx”,”xx”, null, d, t, null, null, onRimoz);
public void RemovedCallback(String strX, Object O,
CacheItemRemovedReason R)
{
// Codice per ricreare l’elemento
Accesso al DB
Cache.Insert(.....)
}
http://www.DevLeap.it
Altre Informazioni
• Dove posso ottenere maggiori informazioni
• www.DevLeap.it
• www.asp.net
• Developer resources
• Microsoft Visual Studio.NET
• Microsoft .NET Framework SDK
• Microsoft Developer Network
http://www.DevLeap.it
ASP.NET Managing State
I vostri feedback sono
importanti
• Scrivetemi
Grazie della partecipazione
– A presto
– [email protected]
http://www.DevLeap.it
Scarica

ASP.NET Managing State