AbpSession只給了userId和TenantId,這次實際項目中並不夠用,網上找了很久也沒找到好的實現方法。項目初期沒有時間進行研究,最近空了試了一下,大致實現添加額外字段並讀取相應值的功能。
本文以實現添加用戶名字字段為例
主要參考以下文章:
一、基於 DDD 的. NET 開發框架 - ABP Session 實現
該文主要介紹了ABP中關於AbpSession的源碼及其實現,注:源碼及其實現請參考此文,本文不做贅述
二、ABP 初探 之 AbpSession 擴展
該文記錄作者對於AbpSession擴展的嘗試,似乎是在源代碼上進行的修改(僅個人猜測),實現方法大致與本文相同,但本文的實現未修改源代碼
三、MVC5 - ASP.NET Identity 登錄原理 - Claims-based 認證和 OWIN
該文介紹並講解了ABP使用的登陸驗證組件 ASP.NET Identity
參考上述文章後大概有一個實現思路,思路如下:
代碼如下:
1 public class MyAbpSession : ClaimsAbpSession
2 {
3 public MyAbpSession(IMultiTenancyConfig multiTenancy) : base(multiTenancy)
4 {
5
6 }
7
8 public virtual string UserName
9 {
10 get
11 {
12 var userIdClaim = PrincipalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == "UserName");
13 return userIdClaim.Value;
14 }
15 }
16 }
1 public override void PreInitialize()
2 {
3 //Enable database based localization
4 Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();
5
6 //替換IAbpSession的實現類
7 Configuration.ReplaceService<IAbpSession, MyAbpSession>(DependencyLifeStyle.Transient);
8
9 }
1 private async Task SignInAsync(User user, ClaimsIdentity identity = null, bool rememberMe = false)
2 {
3
4 if (identity == null)
5 {
6 identity = await _userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
7 }
8 else
9 {
10 //UserName為查詢用標識(key)
11 identity.AddClaim(new Claim("UserName", user.Name));
12 }
13 AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
14 AuthenticationManager.SignIn(new AuthenticationProperties {IsPersistent = rememberMe}, identity);
15 }
經過這些代碼後,設置斷點可查看到,新的session中已經存在我們需要的UserName字段並且數據已經拿到手了。

但是由於IAbpSession接口沒有提供UserName字段,所以這個時候我們是沒有辦法在寫代碼的時候通過AbpSession.UserName來獲取的,這樣做會報錯。當然你可以強制轉換後強行獲取,這樣明顯是不符合我們要求的。
於是參考了ABP的源碼,ABP中有一個擴展類AbpSessionExtensions,實現了通過方法來獲取UserId的值。於是我轉換了一下實現思路
4.通過擴展類,以方法的方式來獲取該值
該擴展實現後原MyAbpSession類已經沒有用了,可以刪去,本文主要從最先思路開始,所以還留著。即最終實現只需要按3、4的步驟進行,無需從一開始。
1 public static class MyAbpSessionExtensions
2 {
3 public static string GetUserName(this IAbpSession session)
4 {
5 //在ABP源碼中也是通過DefaultPrincipalAccessor.Instance來獲取PrincipalAccessor 即此處的DefaultPrincipalAccessor.Instance等價於上文中的PrincipalAccessor
6 var userIdClaim = DefaultPrincipalAccessor.Instance.Principal?.Claims.FirstOrDefault(c => c.Type == "UserName");
7 return userIdClaim.Value;
8 }
9 }
至此可以在代碼中以方法的方式來獲取UserName的值了

附:實在是想不出怎麼以字段的方式來實現(即AbpSession.UserName),除了改ABP源碼修改IAbpSession,只能求其次以方法來實現。菜鳥實力只到這裡,望有大神可以解決此問題
實現過程還是走了彎路的特別是替換IAbpSession的實現類,直接接觸的IOC相關才少,都不知道怎麼換,不過最終還是查到了相關代碼,果然還是要多百度和google。
ABP的求知路還很漫長啊~求基友一起啊