Contesto:dati Persistenza attraverso postback ASP.NET
ho spesso trovato in situazioni in cui le nostre pagine ASP.NET avrebbero dovuto mostrare i dati per l'utente su un GridView, fargli modificarlo a suo piacimento (Casella di testo sulle celle) e salvarlo solo nel database quando effettivamente colpisce il "Pulsante Salva". Questi dati sono di solito uno stato virtuale delle informazioni sulla pagina, il che significa che l'utente può cambiare tutto senza realmente salvarlo fino a quando non preme il pulsante "Salva". In questi casi, è sempre presente un elenco di dati che deve essere mantenuto tra i postback ASP.NET. Questi dati potrebbero essere un'istanza di DataTable
o solo alcuni List<Someclass>
.
Spesso vedo persone che implementano questo e persistono i dati su Session
. In questi casi, inoltre, di solito vedo problemi quando si tratta di un utente che naviga con più schede aperte, alcune volte nella stessa pagina. Dove i dati di due diverse schede verrebbero unite e causerebbero problemi di criptazione delle informazioni.
Esempio di sessione è usato spesso:
private List<SomeClass> DataList
{
get
{
return Session["SomeKey"] as List<SomeClass>;
}
set
{
Session["SomeKey"] = value;
}
}
gente spesso cerca di risolverlo facendo qualcosa di simile a questo:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataList = null
}
else
{
FillGridView(DataList);
}
}
Ma che dire quando due schede sono già caricati e l'utente sta cambiando i valori di GridView e per qualche strano motivo prova a salvare i dati premendo il pulsante Salva sull'altra pagina? Personalmente non mi piace questa opzione.
Altri modi per fare questo sarebbe inserire i dati su ViewState
. Tuttavia, quando si tratta di persistere in elenchi di grandi dimensioni, può influire pesantemente sulla pagina quando viene memorizzata nella pagina (HiddenField
).
Ma qual è il modo migliore per farlo funzionare? Una volta, ho pensato di utilizzare Session
insieme a ViewState
dove lo ViewState
avrebbe conservato un identificatore univoco che indicizzerebbe i dati salvati Session
. Che impedirebbe la condivisione dei dati tra le schede del browser:
private List<SomeClass> DataList
{
get
{
if (ViewState["SomeKey"] == null)
{
ViewState["SomeKey"] = Guid.NewGuid().ToString();
}
return Session[ViewState["SomeKey"].ToString()] as List<SomeClass>;
}
set {
if (ViewState["SomeKey"] == null)
{
ViewState["SomeKey"] = Guid.NewGuid().ToString();
}
Session[ViewState["SomeKey"].ToString()] = value;
}
}
D'altra parte sarebbe memorizzare un nuovo elenco di dati alla sessione ogni volta che l'utente entra nella pagina. Che potrebbe avere un impatto sulla memoria del server. Forse potrebbero essere cancellati in qualche modo.
Domanda:
Quale sarebbe il modo migliore di persistente quel tipo di dati tra Postback, considerando i contesti di più schede sul browser, con il minor costo per il server e per la squadra di manutenzione di codifica ?
Aggiornamento:
Come @nunespascal ben postato, una possibilità potrebbe essere quella di memorizzare il ViewState
nel Session
utilizzando il SessionPageStatePersister
. Ma sfortunatamente non è un'opzione per il mio caso. Eppure non è molto diverso dal mio ultimo esempio, salvando i dati sulla Sessione indicizzati da un UniqueId memorizzato su ViewState.
Ci sarebbero altre opzioni?
Secondo approccio realizzabile con alcune modifiche: 1) utilizzare un campo nascosto anziché ViewState. Questo ti consente di accedervi prima che ViewState sia disponibile sulla pagina (utile a volte). 2) Wrap Session con un manager che limita il numero di elementi che possono essere memorizzati in una sola volta e lancia gli oggetti più vecchi. Naturalmente, questo non risolve completamente il problema di memoria, ma può andare un lungo cammino verso consentendo agli utenti di lavorare organicamente nella vostra applicazione senza preoccuparsi che un utente occupato avrà centinaia di oggetti di grandi dimensioni/set in memoria. –