記AbpSession擴展實現過程

  AbpSession只給了userId和TenantId,此次實際項目中並不夠用,網上找了好久也沒找到好的實現方法。項目初期沒有時間進行研究,最近空了試了一下,大體實現添加額外字段並讀取相應值的功能。html

  本文以實現添加用戶名字字段爲例session

  主要參考如下文章:框架

  1、基於 DDD 的. NET 開發框架 - ABP Session 實現
async

    該文主要介紹了ABP中關於AbpSession的源碼及其實現,注:源碼及其實現請參考此文,本文不作贅述ide

  2、ABP 初探 之 AbpSession 擴展post

    該文記錄做者對於AbpSession擴展的嘗試,彷佛是在源代碼上進行的修改(僅我的猜想),實現方法大體與本文相同,但本文的實現未修改源代碼this

  3、MVC5 - ASP.NET Identity 登陸原理 - Claims-based 認證和 OWINgoogle

    該文介紹並講解了ABP使用的登錄驗證組件 ASP.NET Identity url

 

    參考上述文章後大概有一個實現思路,思路以下:spa

  1.建立一個繼承自ClaimsAbpSession的類,該類中實現本身新加字段的讀取

    代碼以下:

 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     }

  2.替換ABP中IAbpSession接口的實現類ClaimsAbpSession爲MyAbpSession 

  

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          }

  3.用戶登錄後往現有的Claims中插入UserName的Claim

 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類已經沒有用了,能夠刪去,本文主要從最早思路開始,因此還留着。即最終實現只須要按三、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 入門系列(10)——擴展 AbpSession受啓發

  新建IMyAbpSession接口

 

   public interface IMyAbpSession:IAbpSession
    {

        string UserName{ get;}
    }

  並使MyAbpSession繼承該接口,以後再controller和 Service基類中替換原有AbpSession便可以屬性方式來使用

 public new IMyAbpSession AbpSession { get; set; }

  ABP的求知路還很漫長啊~求基友一塊兒啊

相關文章
相關標籤/搜索