一、前言 上篇實戰完成後,沒想到會有那麼多的圈友給了那麼多的支持,甚至連只是作為代碼倉儲的git上也給了一些小星星,真的感覺很惶恐啊,哈哈哈,畢竟代碼寫的很爛啊。由於上一篇只是大概說了下項目,所以準備寫下這篇詳細說下自己對於獲取當前登錄用戶的設計與實現,原本準備上周末就完成的這篇,結果周六一起來,發 ...
一、前言
上篇實戰完成後,沒想到會有那麼多的圈友給了那麼多的支持,甚至連只是作為代碼倉儲的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類如下所示。
1 public static class CurrentUser 2 { 3 #region Initialize 4 5 private static IHttpContextAccessor _httpContextAccessor; 6 7 private static ISession _session => _httpContextAccessor.HttpContext.Session; 8 9 public static void Configure(IHttpContextAccessor httpContextAccessor) 10 { 11 _httpContextAccessor = httpContextAccessor; 12 } 13 14 #endregion 15 16 #region Attribute 17 18 /// <summary> 19 /// 用戶主鍵 20 /// </summary> 21 public static string UserOID 22 { 23 get => _session == null ? "" : _session.GetString("CurrentUser_UserOID"); 24 set => _session.SetString("CurrentUser_UserOID", !string.IsNullOrEmpty(value) ? value : ""); 25 } 26 27 /// <summary> 28 ///用戶編號 29 /// </summary> 30 public static long UserId 31 { 32 get => _session == null ? 0 : Convert.ToInt64(_session.GetString("CurrentUser_UserId")); 33 set => _session.SetString("CurrentUser_UserId", value != 0 ? value.ToString() : "0"); 34 } 35 36 /// <summary> 37 /// 用戶姓名 38 /// </summary> 39 public static string UserName 40 { 41 get => _session == null ? "" : _session.GetString("CurrentUser_UserName"); 42 set => _session.SetString("CurrentUser_UserName", !string.IsNullOrEmpty(value) ? value : ""); 43 } 44 45 /// <summary> 46 /// 用戶登錄賬戶 47 /// </summary> 48 public static string UserAccount 49 { 50 get => _session == null ? "" : _session.GetString("CurrentUser_UserAccount"); 51 set => _session.SetString("CurrentUser_UserAccount", !string.IsNullOrEmpty(value) ? value : ""); 52 } 53 54 /// <summary> 55 /// 用戶頭像地址 56 /// </summary> 57 public static string UserImage 58 { 59 get => _session == null ? "" : _session.GetString("CurrentUser_UserImage"); 60 set => _session.SetString("CurrentUser_UserImage", !string.IsNullOrEmpty(value) ? value : ""); 61 } 62 63 /// <summary> 64 /// 用戶角色 65 /// </summary> 66 public static string UserRole 67 { 68 get => _session == null ? "" : _session.GetString("CurrentUser_UserRole"); 69 set => _session.SetString("CurrentUser_UserRole", !string.IsNullOrEmpty(value) ? value : ""); 70 } 71 72 /// <summary> 73 /// 主頁地址 74 /// </summary> 75 public static string UserPage 76 { 77 get => _session == null ? "" : _session.GetString("CurrentUser_UserPage"); 78 set => _session.SetString("CurrentUser_UserPage", !string.IsNullOrEmpty(value) ? value : ""); 79 } 80 81 #endregion 82 }CurrentUser
當我們創建好了這樣一個靜態類後,我們就可以在登錄成功後,將當前登錄的用戶信息賦值給這個靜態類,這樣我們就可以在需要使用到的地方直接使用CurrentUser這個靜態類即可。在當時實際使用後發現,想要獲取到登錄後存儲的用戶信息,則必須在Controller的構造方法中調用CurrentUser的Configure方法,無形中還是增加了許多的工作量。
Controller的構造函數示例代碼如下:
1 [Area("Administrator")] 2 [Authorize(Policy = "Administrator")] 3 public class HomeController : DanvicController 4 { 5 #region Initialize 6 7 private readonly ApplicationDbContext _context; 8 private readonly ILogger _logger; 9 private readonly IHomeService _service; 10 private readonly IHttpContextAccessor _httpContextAccessor; 11 public HomeController(IHomeService service, ILogger<HomeController> logger, IHttpContextAccessor httpContextAccessor, ApplicationDbContext context) 12 { 13 _service = service; 14 _logger = logger; 15 _httpContextAccessor = httpContextAccessor; 16 _context = context; 17 CurrentUser.Configure(_httpContextAccessor); 18 } 19 20 #endregion 21 22 #region View 23 24 #endregion 25 }HomeController
登錄成功後給CurrentUser賦值的相關代碼如下所示:
1 /// <summary> 2 /// 設置當前登錄用戶 3 /// </summary> 4 public async Task SetCurrentUser(string oid, IHttpContextAccessor httpContextAccessor, ApplicationDbContext context) 5 { 6 CurrentUser.Configure(httpContextAccessor); 7 8 var user = await PSURepository.GetUserByOIDAsync(oid, context); 9 10 if (user != null) 11 { 12 string role = string.Empty; 13 switch (user.AccountType) 14 { 15 case 0: 16 role = "Administrator"; 17 break; 18 case 1: 19 role = "Instructor"; 20 break; 21 case 2: 22 role = "Student"; 23 break; 24 } 25 26 CurrentUser.UserAccount = user.Account; 27 CurrentUser.UserId = user.Id; 28 CurrentUser.UserImage = user.ImageSrc; 29 CurrentUser.UserName = user.Name; 30 CurrentUser.UserOID = user.IdentityUserOID; 31 CurrentUser.UserRole = role; 32 CurrentUser.UserPage = user.HomePage; 33 } 34 }SetCurrentUser
這樣就可以了,當需要使用到當前登錄的用戶信息時,直接CurrentUser.屬性就可以了,整個項目的代碼還是在項目實戰的那個代碼倉庫中,地址點後面:源代碼倉儲,歡迎大家提出更好的解決方案啊。最後,還是要推廣下我的個人博客啊,點擊這裡,去看看我的博客,謝謝啦~~~