日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

DotNetCore Web应用程序中的Session管理

發(fā)布時間:2023/12/4 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DotNetCore Web应用程序中的Session管理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文來自互聯(lián)網(wǎng),由長沙DotNET技術(shù)社區(qū)編譯。如譯文侵犯您的署名權(quán)或版權(quán),請聯(lián)系小編,小編將在24小時內(nèi)刪除。限于譯者的能力有限,個別語句翻譯略顯生硬,還請見諒。

作者簡介:Jon(Jonathan)Seeley,一位資深.NET開發(fā)者,主要從事Asp.NET/Asp.NET CORE/WPF等技術(shù)棧的開發(fā),他的博客地址為https://www.seeleycoder.com/。

查看原文[1]

上個月,我們討論了DotNetCore Web應(yīng)用程序中的Cookie管理,[2]并介紹了通用Cookie服務(wù)。今天,我們將研究一種用于存儲用戶數(shù)據(jù)的替代選項。會話狀態(tài)是鏈接到瀏覽會話的信息的服務(wù)器存儲,讓我們看一下dotnetcore Web應(yīng)用程序中的通用會話管理技術(shù)。

這篇文章的所有代碼都可以在我的GitHub上找到[3]。

開始之前

如果您在該領(lǐng)域工作了一段時間,您可能已經(jīng)注意到很多教程向您展示了如何做某事。我的意思是,那就是他們在那里的權(quán)利嗎?他們通常不會向您顯示的是*

正確地

的操作方法*。我今天要做同樣的事情。可是等等!請允許我快速解釋。今天,我們將在此會話中使用內(nèi)存中會話狀態(tài)。

從本質(zhì)上說,這沒錯,但也不對。對于任何大小的應(yīng)用程序,您都希望使用非易失性會話提供程序。例如Redis,數(shù)據(jù)庫,XML文件或其他內(nèi)容。好吧,Redis實際上也在內(nèi)存中,對嗎?是的,我們不要被語義所困擾。他們將其作為單獨的服務(wù)運行。

入門

假設(shè)您剛剛加載了控制臺并輸入了以下命令:dotnet new mvc -n SessionManager

現(xiàn)在,您擁有一個嶄新的網(wǎng)站品牌,在撰寫本文時,該網(wǎng)站正在使用netcoreapp2.2。精彩。

讓我們打開它并轉(zhuǎn)到Startup.cs文件,然后在ConfigureServices調(diào)用中添加以下幾行。這將注冊ISession到請求生命周期中,并允許我們從httpcontext訪問它。我們還將公開IHttpContextAccessor注入,因為稍后需要使用它。

// have to add this in order to access HttpContext from our own services services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); // register ISession into our HttpContext lifecycle services.AddSession(options => {options.Cookie.HttpOnly = true; });

ISession無法正常注入,但是您可以通過提供者工廠做一些魔術(shù)來將其公開為可注入對象。為了我們的目的,我們不需要,但讓我們假裝您想要。您可以執(zhí)行以下操作:

services.AddScoped(provider => provider.GetRequiredService().HttpContext?.Session);

我們還沒有完成。我們需要指示管道實際使用會話。彈出該Configure方法,并app.UseSession();在app.UseMvc(...)調(diào)用之前添加某處。

添加SessionService

由于我們不會直接注入ISession,因此會出現(xiàn)“我們該怎么辦?”的問題。讓我們創(chuàng)建一個ISessionService并使用一些通用方法進行設(shè)置,以便我們可以序列化/反序列化我們想要的任何內(nèi)容。如果您查看過Cookie管理方面[4]的信息,則看起來非常相似。

public interface ISessionService {T Get<T>(string key);void Set<T>(string key, T value);void Remove(params string[] keys); } public class SessionService : ISessionService {private readonly ISession _session;public SessionService(IHttpContextAccessor httpContextRepository){_session = httpContextRepository.HttpContext.Session;if (_session == null)throw new ArgumentNullException("Session cannot be null.");}public T Get<T>(string key){throw new NotImplementedException();}public void Set<T>(string key, T value){throw new NotImplementedException();}public void Remove(params string[] keys){throw new NotImplementedException();} }

在上面的代碼塊中,我們?yōu)镮SessionService創(chuàng)建了存根,并為實現(xiàn)創(chuàng)建了框架。我們注入了IHttpContextAccessor,然后從HttpContext訪問了Session屬性。我們進行檢查以確保Session不為空。如果您嘗試將其注入通常不具有HttpContext的某個地方(可能是托管服務(wù)等),則可能會發(fā)生這種情況。我們需要跳回到Startup.cs并添加services.AddScoped<ISessionService, SessionService>();到我們的ConfigureServices調(diào)用中。只需在AddSession通話后直接添加即可,但誠實訂購無所謂。

實施SessionService

讓該服務(wù)變得有趣。進入并將以下代碼添加到方法中:

public T Get<T>(string key) {string value = _session.GetString(key);if (string.IsNullOrWhiteSpace(value))return default(T);return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(value); } public void Set<T>(string key, T value) {if (value == null)Remove(key);else_session.SetString(key, Newtonsoft.Json.JsonConvert.SerializeObject(value)); } public void Remove(params string[] keys) {if (keys.IsNullOrEmpty())return;foreach (string key in keys)_session.Remove(key); }

很基本。在該Get方法中,我們從會話中獲取字符串值,如果該字符串值不存在,則返回我們類型的默認值。否則,我們將從JSON反序列化為該類型。Set如果傳遞null或?qū)SON序列化到會話,我們的方法將刪除該值。

我們的Remove方法只是要求會話刪除一個值。您不必先檢查它是否存在,那樣的會話很友好。它確實引用了我添加的擴展方法IsNullOrEmpty,該方法只是檢查IEnumerable(在本例中為字符串數(shù)組)中是否包含任何內(nèi)容。

整合代碼

打開HomeController.cs并對其進行修改,如下所示:

public class HomeController : Controller {private const string c_CONTRIVEDSESSIONKEY = "contrived";private const string c_NAMESESSIONKEY = "basicname";private readonly ISessionService _sessionService;public HomeController(ISessionService sessionService){_sessionService = sessionService;}public IActionResult Index(){var name = _sessionService.Get<string>(c_NAMESESSIONKEY);var contrived = _sessionService.Get<ContrivedValues>("contrived") ?? new ContrivedValues { Name = "Guest" };var viewModel = new HomeViewModel{Name = name,Contrived = contrived};return View(viewModel);}[HttpPost]public IActionResult PostBasic(NameRequest request){_sessionService.Set(c_NAMESESSIONKEY, request.Name);return RedirectToAction(nameof(Index));}[HttpPost]public IActionResult PostContrived(ContrivedValues request){_sessionService.Set(c_CONTRIVEDSESSIONKEY, request);return RedirectToAction(nameof(Index));}public IActionResult DeleteContrived(){_sessionService.Remove(c_CONTRIVEDSESSIONKEY);return RedirectToAction(nameof(Index));}public IActionResult Privacy(){return View();}[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]public IActionResult Error(){return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });} }

在上面的代碼中我們注入我們的新ISessionService進HomeController,然后建立一些非常蹩腳的,以及如何與它進行交互的例子。HomeController:Index例如,該方法將嘗試從會話中獲取字符串值以及一個實例(ContrivedValues如果找不到)或默認實例。我們將它們包裝到viewModel中,然后傳遞到視圖中。

HomeController:PostBasic操作方法接受一個NameRequest崗位價值,并將其設(shè)置到會話中。PostContrived接一個ContrivedValues帖子并設(shè)置它。DeleteContrived將刪除我們的會話對象ContrivedValues。

視圖模型

顯然,以上內(nèi)容尚未編譯。我們需要添加一些模型。進入“模型”文件夾,然后將以下代碼添加到新文件中HomeViewModel.cs。

public class HomeViewModel {public string Name { get; set; }public ContrivedValues Contrived { get; set; } } public class NameRequest {public string Name { get; set; } } public class ContrivedValues {public int? Age { get; set; }public string Name { get; set; } }

Index.cshtml(視圖/主頁) 最后,我們需要更新視圖以處理該演示。

@model SessionManagerDemo.Models.HomeViewModel @{ViewData["Title"] = "Home Page"; } <div class="row"><div class="col-md-3"><h2>Basic Cookie</h2>@if (!string.IsNullOrWhiteSpace(Model.Name)){<p>Your name is: @Model.Name</p>}<form action="@Url.Action("PostBasic")" method="post"><div class="form-group"><label for="name">Name: </label><input type="text" class="form-control" name="name" placeholder="Name" /></div><button type="submit" class="btn btn-primary">Submit</button></form></div><div class="col-md-3"><h2>Cookie w/Default</h2><p>Current values:</p><ul><li>Age: @Model.Contrived.Age</li><li>Name: @Model.Contrived.Name</li></ul><form action="@Url.Action("PostContrived")" method="post"><div class="form-group"><label for="name">Name: </label><input type="text" class="form-control" name="name" placeholder="Name" /></div><div class="form-group"><label for="name">Age: </label><input type="number" class="form-control" name="age" placeholder="Age" /></div><button type="submit" class="btn btn-primary">Submit</button><!-- yeah yeah, I know... this is naughty --><a href="@Url.Action("DeleteContrived")" class="btn btn-danger">Delete</a></form></div> </div>

單元測試

我不會在此處粘貼單元測試,但是GitHub代碼中[5]有一些單元測試也可以體現(xiàn)其功能。ISession在這種情況下,替換的確很有趣,因為我們使用的是ISession.GetString,它實際上是包裝ISession.TryGetValue調(diào)用的擴展方法。隨意看看,看看我是如何做到這一點的。

結(jié)論

DotNetCore Web應(yīng)用程序中的會話管理非常簡單。我們只需要注冊會話中間件和會話服務(wù),但是它本身是非常有限的。添加基于通用的包裝器可以使我們對過程有更多的控制和靈活性。對于除基本以外的任何功能,您都希望使用某種會話狀態(tài)服務(wù)器,而不是使用此示例所示的內(nèi)存中狀態(tài)。

今天發(fā)布的所有代碼都可以在我的GitHub上找到[6]。

References

[1]?查看原文:?https://www.seeleycoder.com/blog/session-management-dotnetcore/#more-413
[2]?DotNetCore Web應(yīng)用程序中的Cookie管理,:?https://www.seeleycoder.com/blog/cookie-management-asp-net-core/
[3]?我的GitHub上找到:?https://github.com/fooberichu150/SessionService
[4]?Cookie管理方面:?https://www.seeleycoder.com/blog/cookie-management-asp-net-core/
[5]?GitHub代碼中:?https://github.com/fooberichu150/SessionService
[6]?我的GitHub上找到:?https://github.com/fooberichu150/SessionService

總結(jié)

以上是生活随笔為你收集整理的DotNetCore Web应用程序中的Session管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。