• 记AbpSession扩展实现过程


      AbpSession只给了userId和TenantId,这次实际项目中并不够用,网上找了很久也没找到好的实现方法。项目初期没有时间进行研究,最近空了试了一下,大致实现添加额外字段并读取相应值的功能。

      本文以实现添加用户名字字段为例

      主要参考以下文章:

      一、基于 DDD 的. NET 开发框架 - ABP Session 实现

        该文主要介绍了ABP中关于AbpSession的源码及其实现,注:源码及其实现请参考此文,本文不做赘述

      二、ABP 初探 之 AbpSession 扩展

        该文记录作者对于AbpSession扩展的尝试,似乎是在源代码上进行的修改(仅个人猜测),实现方法大致与本文相同,但本文的实现未修改源代码

      三、MVC5 - ASP.NET Identity 登录原理 - Claims-based 认证和 OWIN

        该文介绍并讲解了ABP使用的登陆验证组件 ASP.NET Identity 

        参考上述文章后大概有一个实现思路,思路如下:

      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类已经没有用了,可以删去,本文主要从最先思路开始,所以还留着。即最终实现只需要按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 入门系列(10)——扩展 AbpSession受启发

      新建IMyAbpSession接口

       public interface IMyAbpSession:IAbpSession
        {
    
            string UserName{ get;}
        }

      并使MyAbpSession继承该接口,之后再controller和 Service基类中替换原有AbpSession即可以属性方式来使用

     public new IMyAbpSession AbpSession { get; set; }

      ABP的求知路还很漫长啊~求基友一起啊

  • 相关阅读:
    vim可以打开,gvim无法打开
    Ubuntu用apt-get安装时依赖包无法安装
    如何用mm、mmm编译android中的模块
    装饰模式简单的代码
    FileWriter和FileReader简单使用
    TCP/IP、Http、Socket的区别--特别仔细
    surface实例-小球弹起事例
    android中图片的三级缓存cache策略(内存/文件/网络)
    接口回调
    大公司的Java面试题集
  • 原文地址:https://www.cnblogs.com/FYeed/p/6142888.html
Copyright © 2020-2023  润新知