39

Ok, quindi prima di tutto, prima che qualcuno tenti di stabilire che si tratta di una domanda "duplicata"; Ho esaminato la maggior parte dei post su SO per quanto riguarda domande simili, ma anche in combinazione di tutto ciò che è stato detto sono ancora un po 'in un dilemma sul definitivo o forse dovrei dire un accordo unanime su questo.Esiste una best practice e un'alternativa raccomandata alle variabili di sessione in MVC

posso però dire che ho (sulla base dei messaggi) definitivamente stabilito che la risposta si basa sulla portata del requisito. Ma anche tenendo conto di ciò, le opinioni mi sembrano troppo diverse per prendere una decisione su come gestirle.

Il mio requisito immediato è che ho bisogno di mantenere i dati variabili da 1 controller su più viste. Più specificamente, ho un controller e una vista corrispondente che gestisce i conteggi degli articoli del carrello degli acquisti e vorrei mantenere tali dati su più viste. Sto pensando che la vista _layout sia la scelta più logica per questo.

Ora ho compiuto con successo questo compito assegnando il valore a una variabile di sessione che viene recuperato dal mio punto di vista _layout; quindi, anche quando l'utente doveva navigare in qualsiasi punto del sito, il numero di articoli nel Carrello rimarrà fino a quando non lasciano il sito o completano il checkout; nel qual caso la variabile verrà cancellata nel codice.

I messaggi che ho letto sembrava di parte a uno stare lontano da variabili di sessione a favore di Cookies e memorizzare i dati in un database; o affermando che per lo scopo intento per il quale propongo di usarli, le variabili di Session sono perfettamente adatte all'uso.

L'altra cosa che ho letto suggerisce che le variabili di sessione possono potenzialmente ostacolano le prestazioni complessive se non v'è ad alto traffico sul sito in quanto le informazioni sono memorizzate sul server.

Personalmente non riesco a giustificare la memorizzazione di questo tipo di informazioni in un database e successivamente a colpire il database come immagino che ciò possa influire anche sulle prestazioni del sito e sembra un po 'eccessivo per la memorizzazione di dati temporanei. TempData, ViewData e ViewBag non funzionano nella persistenza dei dati in modo che non siano scelte logiche per il requisito IMO.

Se v'è un altro ben si adatta alternativa alla variabile di sessione (che sta lavorando per me) vorrei sapere di cosa si tratta.

2 messaggi che sembrano contraddittorie nello sforzo di fornire migliori raccomandazioni mi lasciano un po 'confuso.

Contro: Is it a good practice to avoid using Session State in ASP.NET MVC? If yes, why and how?

Pro: Still ok to use Session variables in ASP.NET mvc, or is there a better alternative for some things (like a cart)

sembra che questa domanda (anche se presentato in molte varianti) non ha una risposta definitiva che posso concludere.

Se c'è un modo più preferibile per realizzare questo senza eccessivo, allora questa è la risposta che sono alla ricerca di.

Ho letto da qualche parte l'uso dei filtri MVC in tandem con la sezione di avvio dell'applicazione Global.ascx, ma questo non sembra appropriato per le variabili impostate a livello di controller quanto forse, variabili statiche.

Qualcuno potrebbe forse schiacciare (per mancanza di una parola migliore) le molte opinioni diverse sull'argomento e magari fornire una risposta più definitiva alla domanda? Sono sicuro che le diverse opinioni hanno il loro posto e non sto cercando di screditarli.Ma avere una risposta definitiva e possibilmente unanime sarebbe meglio; quindi ho potuto ordinare gli altri post per determinare cosa è meglio per la mia applicazione.

Naturalmente, se questa domanda non ha una risposta definitiva; dimmelo e tenterò di ricavare la mia risposta dagli altri post.

Grazie

========================================= ==================

rISPOSTA aggiornato per risposte fornite

Caching e Cookies sembra essere una preferenza generale dalle risposte però ho anche notato il affermazione che la memorizzazione nella cache non è un candidato ideale da utilizzare su più server Web perché la sincronizzazione può essere un potenziale problema.

Dare credito alla Tim, è dichiarato che immagazzinamento di dati verrà ottimizzato e gli utenti hanno la possibilità di tornare in un secondo momento e continuare da dove avevano lasciato.

Questo è un ottimo punto, ma mantenendo la previsione sulle probabilità; è probabile che sia ragionevole dato che alcuni utenti potrebbero non tornare lasciando dati non necessari nel database.

Pertanto, mantenere il DB ottimizzato e pulito (che "per me" è di uguale importanza) richiederebbe l'implementazione di un'attività di manutenzione per la scadenza automatica di quei record in base a una soglia di tempo impostata per tenere conto di tali circostanze. Anche se un'attività di manutenzione non è un'opzione indiscutibile, ritengo comunque che questo aggiunga un po 'più di lavoro all'attività semplicemente allo scopo inteso di servire come memoria temporanea.

Ciò nonostante, lo faccio rispettare la raccomandazione di Tim e credo che merita di merito sulla lotta contro il mio parere iniziale ad un grado; che un database non sembra essere un'opzione praticabile per la memorizzazione di dati temporanei; quindi penso che il compromesso sarebbe quello di memorizzare i dati in un database (dato lo scenario di un carrello della spesa o simile), magari dopo un checkout. In questo modo, come affermato in precedenza, i dati possono essere rintracciati in modo persistente nelle visite successive in modo da avere un record di transazioni. Ma ancora più importante, sarebbero i dati di quelle transazioni che hanno reale rilevanza per persistere nel database.

È stato anche affermato che, anche se è più veloce di sessione di database; ma nonostante abbia i suoi avvertimenti che in qualche modo possono essere mitigati da altri meccanismi come l'attribuzione dell'attributo SessionStateBehavior, che serve solo come esempio.

ma ... credo Erik tipo di ha spinto il punto a casa con l'effetto Dunning-Kruger. Sebbene, dal contenuto e dalle spiegazioni per le risposte proposte date qui; Dubito seriamente che l'esperienza di una delle persone che hanno risposto sia in qualche modo discutibile. Nondimeno, tendo ad essere d'accordo sul fatto che ottenere un'opinione unanime potrebbe essere in qualche modo più che ragionevole aspettativa da parte mia.

Quello che stavo più specificamente alla ricerca di un consenso generale per una tecnica che avrebbe ospitare comodamente un svariato numero di scenari. In altre parole, qualcosa che soddisferà non solo il mio particolare scenario ma fornirà anche l'elemento di scalabilità agli ambienti più grandi con un traffico potenzialmente più pesante. In questo modo un cambiamento nella programmazione potrebbe essere alleviato del tutto o minimo nella migliore delle ipotesi.

========================================= ====

Sintesi sulla base del feedback:

  1. variabili di sessione sembrano accogliere scenari più piccoli e se del caso, ma hanno un certo potenziale per problemi di persistenza tra le altre discrepanze notevoli come dichiarato molto divertiti da Erik. Quindi questa opzione ovviamente non si adatta a un modello scalabile.

  2. Il caching è preferibile rispetto alle variabili Session, ma ancora una volta non necessariamente la "migliore" opzione scalabile dovuta, tra le altre cose, alle potenziali complessità di sincronizzazione negli ambienti di server Web server come precedentemente indicato. Ma un'opzione comunque.

  3. Lo spazio di archiviazione del database è scalabile ma, per lo scopo previsto, la memorizzazione temporanea volatile non è probabilmente l'opzione più elegante dal punto di vista del database poiché richiederebbe una pulizia periodica. Personalmente, avendo una solida base nei concetti di database precedenti nella mia carriera, questo probabilmente non sarà qualcosa con cui molti sviluppatori saranno probabilmente d'accordo; ma utilizzare il database per questo scopo può essere sufficiente per lo sviluppo Web dal punto di vista dei programmatori; tuttavia dal punto di vista dello sviluppo di DAL e DB questo (per me) ha il potenziale per imporre un task DB aggiuntivo per imporre un backend efficiente.

  4. I cookie sembrano essere una buona opzione con gli elementi "desiderabili" combinati delle variabili di sessione e della memorizzazione nella cache.

=========================================== =======

CONCLUSIONE

sulla base delle risposte; Penso che i COOKIE e il CACHING sembrino essere generalmente proposte ben arrotondate per le migliori pratiche su tutta la linea, in combinazione con lo storage del database quando è richiesta una persistente persistenza dopo il fatto; come candidati potenzialmente validi per la scalabilità di quelli presentati.

La scelta definitiva tra i 2 sembra essere basata sulla quantità e il tipo di dati che richiedono la memorizzazione (ad esempio, sensibile vs non sensibile e se non vi è alcuna preoccupazione che il cliente possa modificare i dati sul loro fine) ; oltre a considerazioni speciali per i COOKIES nel fatto che possono essere disabilitati dai clienti.

Ovviamente, non esiste una soluzione adatta a tutte le soluzioni come chiaramente indicato e concluso dalle risposte fornite ma in termini di scalabilità; Potrei sbagliarmi ma queste sembrano essere le MIGLIORI scelte disponibili.

Perché tutte le risposte sono buone; Sto abbastanza andando ad accreditare tutti i post come utili e andando ad accettare la risposta di Erik come una soluzione scalabile complessiva ben arrotondata. Vorrei poter selezionare più di una risposta accettata in quanto ritengo che la risposta di Tim sia stata anche ben definita e concisa.

Anche la risposta di Gupta era buona, ma volevo più elaborazione della risposta proposta e non una ripetizione di post precedenti.

Grazie Ragazzi!

+2

Mi piace questa domanda, anche se potrebbe essere più adatta a [Programmatori] (http://programmers.stackexchange.com/). –

+1

Grazie, questo è stato davvero utile per me, così come sono attualmente umming e aaahing oltre se memorizzare un singolo valore in una sessione, cookie o qualcos'altro. Nel mio caso, quando un utente accede al mio sito, viene restituito un valore non identificabile che deve persistere attraverso un sito non intensivo. – kolin

+1

Un'altra possibile soluzione, che è più fattibile oggi rispetto a quando è stata posta questa domanda, è l'archiviazione locale di HTTP 5. Questo è ora molto più ampiamente supportato (anche se potresti ancora incontrare dei problemi con alcuni browser mobili, e ovviamente le persone continuano a utilizzare browser desktop molto vecchi). –

risposta

23

Lei non potrà mai ottenere parere unanime su qualsiasi cosa in qualsiasi grande gruppo di persone. Questa è solo la natura umana. Parte di ciò deriva dal numero Dunning-Kruger Effect che afferma che meno qualcuno conosce un argomento, più è probabile che stiano valutando troppo la propria esperienza in quell'argomento. In altre parole, molte persone pensano di sapere qualcosa, ma solo perché non sanno di non saperlo. In parte è semplicemente che le persone hanno esperienze diverse, e alcuni non hanno riscontrato problemi con la sessione, mentre altri hanno in varie situazioni, o viceversa ...

Quindi, per eseguire il backup della ricerca, che suggerisce che la risposta dipende fortemente sui requisiti, abbiamo bisogno di capire quali sono le vostre esigenze. Se si tratta di un sito ad alto traffico, con server con bilanciamento del carico in una web farm, resta il più lontano possibile dalla sessione. Certo, è possibile condividere la sessione in vari modi in un ambiente di server farm (server di sessione, server di cache di distribuzione, ecc.), Ma evitando la sessione sarà quasi sempre più veloce se si può aiutare.

Se il tuo sito è un server singolo, e difficilmente potrà crescere oltre. E i tuoi modelli di traffico sono relativamente bassi, quindi la sessione potrebbe essere un'opzione utile. Tuttavia, dovresti sempre essere consapevole del fatto che la sessione non è affidabile e può scomparire in qualsiasi momento. Se il pool di applicazioni viene riciclato, la sessione è sparita. Se un'eccezione non rilevata raggiunge il processo di lavoro, la sessione potrebbe non essere più disponibile. Se IIS pensa che non ci sia abbastanza memoria, la sessione potrebbe essere sparita, indipendentemente dai valori di timeout configurati. Inoltre, non è sempre possibile ricevere notifiche attendibili sul fatto che una sessione è terminata, poiché le sessioni terminate non attivano l'evento Session_End.

Un altro problema è che la sessione è serializzata. In altre parole, IIS impedisce a più thread di scrivere alla sessione alla volta, e spesso lo fa bloccando la sessione mentre un thread è in esecuzione se non ha disattivato il blocco della sessione scrivibile. Ciò può causare gravi problemi in alcuni casi e semplicemente scarse prestazioni in altri. È possibile attenuare questo fenomeno contrassegnando vari metodi con un attributo di sessione di sola lettura se non si intende modificarlo in tale metodo.

In definitiva, se si sceglie di utilizzare la sessione, quindi provare a usarlo solo per le cose piccole, di breve durata, se possibile, e se non possibile, costruire in un modo per "rigenerare" i dati se la sessione è perduto. Ad esempio, utilizzando il numero di articoli nel carrello di esempio, è possibile scrivere un metodo che prima controlla se il valore è presente e, in caso contrario, si spegne e lo carica dal database. Usa sempre questo metodo per accedere alla variabile, piuttosto che accedervi direttamente dalla sessione ... in questo modo, se la sessione viene persa, la ricaricherà.

Tuttavia, detto questo ...Per il numero di articoli in un carrello, generalmente preferisco utilizzare un cookie per queste informazioni, poiché i cookie vengono comunque passati alla pagina su ogni caricamento, e questa è una piccola unità di dati discreti. Generalmente preferisci Sessione per i dati sensibili che vuoi impedire all'utente di essere in grado di cambiare ... il numero di elementi nel carrello semplicemente non si adatta a questa regola.

3

Session alternativa in diverse prospettive: -

Quando si tiene qualcosa in sessione si rompe la regola primaria in ASP.NET MVC.È possibile utilizzare queste opzioni come alternativa alla sessione.

Se la sessione asp.net (MVC) esegue il boxing unboxing sull'oggetto, viene eseguito un piccolo carico sul server. Prova questa idea

  1. Caching: - memorizzazione di una lista o di qualcosa di simile a grandi quantità di dati in sessione è meglio può andare bene in Caching. Hai il controllo su quando vuoi che scada piuttosto che sessione utente.

  2. Se l'app dipende dai dati JSON/Ajax, è possibile utilizzare alcune funzionalità fornite in html5 (come WebSQL, IndexDB). non userà il cookie in modo da poter salvare del carico di lavoro sul server.

+1

Un buon punto per quanto riguarda le variabili di sessione Gupta e le opzioni proposte sono degne di nota. Ma stavo cercando specifiche raccomandazioni per le migliori pratiche e perché. Questa informazione è sicuramente utile comunque. Grazie! – Mark

9

Quando

database sono ottimizzati. Un valore semplice come il conteggio di un carrello della spesa è un buon candidato per il caching dal database e (si spera) economico da calcolare a titolo definitivo. Potrebbe essere un non-problema.

Tuttavia, se hai escluso altri meccanismi, i valori piccoli, utente per utente, sono validi candidati per la sessione.

Cache va bene per valori a livello di sito o valori specifici dell'utente con chiavi univoche. Tuttavia, la sincronizzazione delle cache su più server Web può essere difficile. Lo stato della sessione fuori processo rimarrà sincronizzato perché è archiviato in un'unica posizione (database o server di stato).

Naturalmente, ci sono molte alternative di caching di terze parti con varie opzioni per mantenerle sincronizzate.

Indipendentemente da dove viene memorizzato temporaneamente il conto, sono dell'opinione che i carrelli degli acquisti devono essere memorizzati nel database in modo che gli utenti possano tornare in un secondo momento e riprendere da dove avevano lasciato.

prestazioni

Se si utilizza dal processo lo stato della sessione (ad esempio in un ambiente equilibrato carico e/o per effettuare la sessione più durevole), si sarà colpito un database o chiamare un fuori servizio processo, ma la chiamata è relativamente economica a meno che non si stiano serializzando grafici di oggetti di grandi dimensioni.

La sessione viene caricata una volta per richiesta. L'accesso alla lettura successivo è molto veloce.

La scrittura in sessione può essere dannosa per le prestazioni, anche in assenza di carico. Perché? le applicazioni più moderne utilizzano chiamate asincrone e quando più chiamate asincrone colpiscono un gestore HTTP (pagina, controller, ecc.) che legge/scrive sessione, ASP.Net bloccherà la sessione per serializzare l'accesso. Per evitare questo, si può decorare con i controller [SessionState(SessionStateBehavior.ReadOnly)]

design

Ora ho compiuto con successo questo compito assegnando il valore a una variabile di sessione che viene recuperato dal mio punto di vista _layout;

Questo sembra come preoccupazioni di miscelazione, cioè aventi la vista conosce il meccanismo storage sottostante. Da un punto di vista purista, imposterò questo valore su un modello di vista o almeno lo inserirò nello ViewBag.Da un punto di vista pratico, uno o due valori recuperati in questo modo probabilmente non danneggeranno nulla, ma fate attenzione a lasciarlo crescere ulteriormente.

ho letto da qualche parte l'uso di filtri MVC in tandem con la sezione iniziale applicazione Global.ascx pure, ma questo non sembra opportuno per le variabili impostate a livello di controller, per quanto forse, statici variabili .

Le variabili statiche hanno usi perfettamente legittimi, ma è necessario comprenderle a fondo o rischiare problemi gravi.

Vedi le mie risposte di pertinenza di variabili statiche in ASP.Net:

+1

Grazie Tim. Informazioni eccellenti riguardanti le opzioni variabili statiche che inserirò tra i segnalibri. Ho anche esplorato l'attributo SessionState decorativo prima del mio post, ma non mi piaceva molto usarlo per questo. – Mark

+1

Inoltre, grazie per aver sottolineato il potenziale mix di preoccupazioni con il mio attuale design – Mark