Asp.net-Mvc

是否有最佳實踐和推薦替代 MVC 中的 Session 變數

  • May 2, 2014

好的,所以首先在任何人試圖確定這是一個“重複”問題之前;我已經查看了關於類似問題的大多數關於 SO 的文章,但即使結合所有已經說過的內容,我仍然有點左右為難,或者我應該對此表示一致同意。

但是,我可以說我(根據文章)最終確定答案是基於要求的範圍。但即使考慮到這一點,對於我應該如何處理這個問題,意見似乎也太多樣化了。

我的直接要求是我需要在多個視圖中保留來自 1 個控制器的變數數據。更具體地說,我有一個控制器和相應的視圖來處理購物車項目計數,並且我想在多個視圖中保留該數據。我認為 _layout 視圖是最合乎邏輯的選擇。

現在,我通過將值分配給從我的 _layout 視圖中檢索到的 Session 變數成功地完成了這項任務;因此,即使使用者在網站內的任何位置導航,購物車中的商品數量也會持續存在,直到他們離開網站或完成結帳為止;在這種情況下,變數將在程式碼中被清除。

我讀過的文章似乎偏向於遠離 Session 變數以支持 Cookie 並將數據儲存在數據庫中;或說明出於我建議使用它們的目的,會話變數非常適合使用。

我讀過的另一件事表明,如果站點上的流量很高,會話變數可能會阻礙整體性能,因為資訊儲存在伺服器上。

我個人無法證明將此類資訊儲存在數據庫中並隨後訪問數據庫是合理的,因為我認為這也會影響站點性能,並且對於儲存臨時數據似乎有點矯枉過正。TempData、ViewData 和 ViewBag 在持久化數據方面不起作用,因此它們不是 IMO 要求的邏輯選擇。

如果有另一個非常適合的替代 Session 變數(這對我有用),我想知道它是什麼。

2 個在提供最佳建議方面似乎相互矛盾的文章讓我有點困惑。

缺點:避免在 ASP.NET MVC 中使用會話狀態是一種好習慣嗎?如果是,為什麼以及如何?

優點:仍然可以在 ASP.NET mvc 中使用 Session 變數,或者是否有更好的替代方案(例如購物車)

似乎這個問題(儘管以許多不同的變體形式出現)沒有我可以得出的明確答案。

如果有一種更可取的方法來實現這一點而不會過度殺傷,那麼這就是我正在尋找的答案。

我在某處也讀到了 MVC 過濾器與 Global.ascx 應用程序啟動部分的結合使用,但這似乎不適用於在控制器級別設置的變數,就像靜態變數一樣。

有人可能會壓制(因為沒有更好的詞)關於該主題的許多不同意見,並可能為該問題提供更明確的答案嗎?我敢肯定,不同的意見各有所長,我並沒有試圖抹黑他們。但是有一個明確且可能一致的答案會更好;然後我可以對其他文章進行排序,以確定最適合我的應用程序的內容。

當然,如果這個問題沒有確定的答案;告訴我,我會嘗試從其他文章中得出我自己的答案。

謝謝

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

對所提供答案的更新回應

記憶體和 Cookie 似乎是響應中的普遍偏好,但我也注意到記憶體不是跨多個 Web 伺服器使用的理想候選者的聲明,因為同步可能是一個潛在問題。

歸功於 Tim,據說數據庫儲存已經過優化,使用者可以選擇稍後返回並繼續他們離開的地方。

這是一個很好的觀點,但要對機率保持遠見;考慮到某些使用者可能不會返回而在數據庫中留下不必要的數據,這可能是合理的。

因此,保持數據庫優化和清潔(“對我而言”具有同等相關性)將需要實施維護任務,以根據設定的時間門檻值自動使這些記錄過期,以解決這些情況。儘管維護任務不是一個毫無疑問的選擇,但我仍然認為這只是為了作為臨時儲存的目的而為任務增加了一點工作。

儘管如此,我確實尊重蒂姆的建議,並相信在一定程度上反駁我最初的意見是值得的。數據庫似乎不是儲存臨時數據的可行選擇;所以我認為折衷方案是在結帳後將數據儲存在數據庫中(考慮到購物車或類似情況)。如您之前所述,通過這種方式,可以在後續訪問時持續跟踪數據,以便您擁有交易記錄。但更重要的是,將那些具有真正相關性的事務的數據持久化到數據庫中。

也有人說,雖然 Session 比 Database 快;但儘管有一些警告,但在某種程度上可以通過其他機制(例如利用 SessionStateBehavior 屬性)來緩解,這只是一個範例。

但是…我認為 Erik 用 Dunning-Kruger 效應把觀點帶回家了。雖然,從這裡給出的建議答案的內容和解釋來看;我嚴重懷疑任何做出回應的人的專業知識是否值得懷疑。儘管如此,我傾向於同意獲得一致意見的事實可能有點高於我的合理期望。

我更具體地尋找的是一種能夠輕鬆適應多種場景的技術的普遍共識。換句話說,它不僅可以適應我的特定場景,還可以為具有潛在更重流量的更大環境提供可擴展性元素。這樣一來,程式的變化要麼完全緩解,要麼至多是最小的。

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

根據回饋總結:

  1. 會話變數似乎適用於較小的案例場景並且在適用時,但正如 Erik 非常透徹地指出的那樣,它們在其他顯著差異中存在一些持久性問題的可能性。所以這個選項顯然不適合可擴展的模型。
  2. 記憶體比 Session 變數更可取,但也不一定是“最佳”可擴展選項,因為除其他外,如前所述,Web 伺服器場環境中潛在的同步複雜性。但仍然是一個選擇。
  3. 數據庫儲存是可擴展的,但出於臨時易失性儲存的目的,從數據庫的角度來看,它可能不是最優雅的選擇,因為它需要定期清理。就我個人而言,在我職業生涯的早期,我在數據庫概念方面打下了堅實的基礎,這可能不會是許多開發人員可能會同意的;但是從程序員的角度來看,為此目的使用數據庫可能就足夠了 Web 開發;然而,從 DAL 和 DB 開發的角度來看,這(對我而言)有可能強制執行額外的 DB 任務來強制執行高效的後端。
  4. Cookie 似乎是一個不錯的選擇,它結合了會話變數和記憶體的“理想”元素。

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

結論

根據答案;我認為,當事後需要持續的持久性時,COOKIES 和 CACHING 似乎是全面的建議,用於全面結合數據庫儲存的最佳實踐;作為所提出的可擴展性的潛在良好候選者。

兩者之間的最終選擇似乎是基於需要儲存的數據的數量和類型(例如敏感與非敏感,以及是否擔心客戶可能會最終更改數據);除了對 COOKIES 的特殊考慮之外,它們可能會被客戶禁用。

顯然,沒有一種適合所有解決方案的解決方案,正如從提供的答案中明確指出和得出的結論,但在可擴展性方面;我可能錯了,但這些似乎是最好的選擇。

因為所有的反應都很好;我相當認為所有文章都是有用的,並接受 Erik 的回答作為一個全面的整體可擴展解決方案。我希望我可以選擇多個被接受的答案,因為我相信蒂姆的回答也非常簡潔明了。

Gupta 的反應也很好,但我想更詳細地闡述建議的答案,而不是重複以前的文章。

多謝你們!

在任何一大群人中,你永遠不會對任何事情達成一致意見。這只是人的本性。部分原因在於鄧寧-克魯格效應,即人們對某個主題的了解越少,他們就越有可能高估自己在該主題上的專業知識。換句話說,很多人認為他們知道某事,但只是因為他們不知道他們不知道。部分原因只是人們有不同的經歷,有些人在會話中沒有發現問題,而有些人在各種情況下都有,反之亦然……

因此,為了支持您的研究,這表明答案在很大程度上取決於需求,我們需要了解您的需求是什麼。如果這是一個高流量站點,在 Web 場中具有負載平衡的伺服器,那麼盡可能遠離會話。當然,可以在伺服器場環境(會話伺服器、分佈式記憶體伺服器等)中以各種方式共享會話,但如果你能提供幫助,避免會話幾乎總是會更快。

如果您的站點是單個伺服器,並且不太可能超出此範圍。並且您的流量模式相對較低,那麼會話可能是一個有用的選項。但是,您應該始終意識到會話是不可靠的儲存,並且可能隨時消失在您身上。如果應用程序池被回收,會話就消失了。如果未擷取的異常冒泡到工作程序,則會話可能會消失。如果 IIS 認為沒有足夠的記憶體,您的會話可能會消失,而不管配置了任何超時值。您也不能總是得到會話結束的可靠通知,因為終止的會話不會觸發 Session_End 事件。

另一個問題是 Session 是序列化的。換句話說,IIS 一次阻止多個執行緒寫入會話,並且它通常通過線上程執行時鎖定會話來實現這一點,如果它沒有選擇退出可寫會話鎖定。在某些情況下,這可能會導致嚴重的問題,而在其他情況下只會導致性能不佳。如果您不打算在該方法中修改它,您可以通過使用只讀會話屬性標記各種方法來緩解這種情況。

最終,如果您確實選擇使用會話,那麼盡可能只將它用於小的、短暫的事情,如果不可能,那麼如果會話失去,則建構一種“重新生成”數據的方式。例如,以購物車中的商品數量為例,您可以編寫一個方法,首先檢查該值是否存在,如果不存在,則將其從數據庫中載入。始終使用此方法訪問變數,而不是直接從會話中訪問它……這樣,如果會話失去,它將重新載入它。

但是,話雖如此…對於購物車中的商品數量,我通常更喜歡使用 cookie 來獲取此資訊,因為 cookie 無論如何都會在每次載入時傳遞到頁面,這是一個小的離散數據單元. 通常更喜歡 Session 用於您希望阻止使用者更改的敏感數據。購物車中的商品數量根本不符合該規則。

引用自:https://stackoverflow.com/questions/23419011