一、前言
上篇實戰完成后,沒想到會有那么多的圈友給了那么多的支持,甚至連只是作為代碼倉儲的git上也給了一些小星星,真的感覺很惶恐啊,哈哈哈,畢竟代碼寫的很爛啊。由於上一篇只是大概說了下項目,所以准備寫下這篇詳細說下自己對於獲取當前登錄用戶的設計與實現,原本准備上周末就完成的這篇,結果周六一起來,發現自己起水痘了,嗯,很悲催。。。請了一個星期的假,今天好歹頭不痛,不發燒能看電腦了,就努力努力趕出來吧。
獲取當前登錄用戶的整體思路,我們可以通過創建一個靜態的用戶類,存儲當前登錄的用戶。通過將屬性值存儲在session中,從而存儲到服務器的內存中,做到可以在系統全局中獲取當前登錄用戶的數據信息。
.NET Framework平台下面的MVC與.NET Core平台下面的MVC,對於Session的使用上存在着一些的差異,主要在於如何獲取到Session對象。在傳統的MVC項目中我們可以直接使用HttpContext.Current.Session獲取到session,從而做到對於數據的取值、賦值;而在ASP.NET Core MVC中,並沒有HttpContext.Current.Session這個靜態類,通過查閱微軟的文檔可知,我們可以通過注入IHttpContextAccessor對象的方式從而獲取到session對象,解決方案如下所示。
二、使用Session存儲當前登錄的用戶信息
首先,在ASP.NET Core 中使用Session,我們需要將Session注入到ASP.NET Core的管道(pipeline)中,和我們使用MVC的方式相同,在ConfigureServices(IServiceCollection services)中,添加
1 services.AddSession();
在Configure(IApplicationBuilder app, IHostingEnvironment env)中添加
1 app.UseSession();
這樣,我們就可以在MVC中使用到Session了。當然現在也只是能在Controller中獲取到Session對象,如果想在別的類文件中使用到Session對象,我們需要注入IHttpContextAccessor對象。這里,我們可以使用nuget添加Microsoft.AspNetCore.Http.Extensions這個程序集,方便我們對於Session進行操作。
因為我們采用靜態類作為當前登錄用戶的載體,而靜態類不能擁有實例構造函數,所以我采用創建一個配置方法來進行注入,CurrentUser類如下所示。
public static class CurrentUser { #region Initialize private static IHttpContextAccessor _httpContextAccessor; private static ISession _session => _httpContextAccessor.HttpContext.Session; public static void Configure(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } #endregion #region Attribute /// <summary> /// 用戶主鍵 /// </summary> public static string UserOID { get => _session == null ? "" : _session.GetString("CurrentUser_UserOID"); set => _session.SetString("CurrentUser_UserOID", !string.IsNullOrEmpty(value) ? value : ""); } /// <summary> ///用戶編號 /// </summary> public static long UserId { get => _session == null ? 0 : Convert.ToInt64(_session.GetString("CurrentUser_UserId")); set => _session.SetString("CurrentUser_UserId", value != 0 ? value.ToString() : "0"); } /// <summary> /// 用戶姓名 /// </summary> public static string UserName { get => _session == null ? "" : _session.GetString("CurrentUser_UserName"); set => _session.SetString("CurrentUser_UserName", !string.IsNullOrEmpty(value) ? value : ""); } /// <summary> /// 用戶登錄賬戶 /// </summary> public static string UserAccount { get => _session == null ? "" : _session.GetString("CurrentUser_UserAccount"); set => _session.SetString("CurrentUser_UserAccount", !string.IsNullOrEmpty(value) ? value : ""); } /// <summary> /// 用戶頭像地址 /// </summary> public static string UserImage { get => _session == null ? "" : _session.GetString("CurrentUser_UserImage"); set => _session.SetString("CurrentUser_UserImage", !string.IsNullOrEmpty(value) ? value : ""); } /// <summary> /// 用戶角色 /// </summary> public static string UserRole { get => _session == null ? "" : _session.GetString("CurrentUser_UserRole"); set => _session.SetString("CurrentUser_UserRole", !string.IsNullOrEmpty(value) ? value : ""); } /// <summary> /// 主頁地址 /// </summary> public static string UserPage { get => _session == null ? "" : _session.GetString("CurrentUser_UserPage"); set => _session.SetString("CurrentUser_UserPage", !string.IsNullOrEmpty(value) ? value : ""); } #endregion }
當我們創建好了這樣一個靜態類后,我們就可以在登錄成功后,將當前登錄的用戶信息賦值給這個靜態類,這樣我們就可以在需要使用到的地方直接使用CurrentUser這個靜態類即可。在當時實際使用后發現,想要獲取到登錄后存儲的用戶信息,則必須在Controller的構造方法中調用CurrentUser的Configure方法,無形中還是增加了許多的工作量。
Controller的構造函數示例代碼如下:
[Area("Administrator")] [Authorize(Policy = "Administrator")] public class HomeController : DanvicController { #region Initialize private readonly ApplicationDbContext _context; private readonly ILogger _logger; private readonly IHomeService _service; private readonly IHttpContextAccessor _httpContextAccessor; public HomeController(IHomeService service, ILogger<HomeController> logger, IHttpContextAccessor httpContextAccessor, ApplicationDbContext context) { _service = service; _logger = logger; _httpContextAccessor = httpContextAccessor; _context = context; CurrentUser.Configure(_httpContextAccessor); } #endregion #region View #endregion }
登錄成功后給CurrentUser賦值的相關代碼如下所示:
/// <summary> /// 設置當前登錄用戶 /// </summary> public async Task SetCurrentUser(string oid, IHttpContextAccessor httpContextAccessor, ApplicationDbContext context) { CurrentUser.Configure(httpContextAccessor); var user = await PSURepository.GetUserByOIDAsync(oid, context); if (user != null) { string role = string.Empty; switch (user.AccountType) { case 0: role = "Administrator"; break; case 1: role = "Instructor"; break; case 2: role = "Student"; break; } CurrentUser.UserAccount = user.Account; CurrentUser.UserId = user.Id; CurrentUser.UserImage = user.ImageSrc; CurrentUser.UserName = user.Name; CurrentUser.UserOID = user.IdentityUserOID; CurrentUser.UserRole = role; CurrentUser.UserPage = user.HomePage; } }
這樣就可以了,當需要使用到當前登錄的用戶信息時,直接CurrentUser.屬性就可以了,整個項目的代碼還是在項目實戰的那個代碼倉庫中,地址點后面:源代碼倉儲,歡迎大家提出更好的解決方案啊。最后,還是要推廣下我的個人博客啊,點擊這里,去看看我的博客,謝謝啦~~~
