重写abp框架UserManager类

背景:用过abp框架的应该都知道,abp框架会封装一些成熟的类方法提供给使用者来使用,用来操作 一些内置的实体类(类中一些字段设置为了protected internal),比如IdentityUser、IdentityRole等。但是这些封装的方法总是会有各种各样的校验,当然如果我们没有特殊需求,可以直接使用它提供的方法,本文就是基于创建、更新用户信息时,用户名重复的校验所写,像密码规则的校验,这里预留了参数来操作校验与否。

1.在Domain层创建UserManager
这里我们继承了UserManager的泛型类,这是为了偷个懒,毕竟不是要重写所有的方法,其他的方法我们可继续使用。
创建用户

public virtual async Task<IdentityResult> CreateAsync(IdentityUser user, string password, bool validatePassword = false)
{
    ThrowIfDisposed();
    if (user == null)
    {
        throw new ArgumentNullException(nameof(user));
    }
    if (string.IsNullOrEmpty(password))
    {
        throw new ArgumentNullException(nameof(password));
    }
    var result = await SetPasswordHashAsync(user, password,validatePassword);
    if (!result.Succeeded)
    {
        return result;
    }
    return await CreateAsync(user);
}

public override async Task<IdentityResult> CreateAsync(IdentityUser user)
{
    this.ThrowIfDisposed();
    await SetLockoutEnabledAsync(user, true);
    await UpdateNormalizedUserNameAsync(user);
    await UpdateNormalizedEmailAsync(user);
    return await Store.CreateAsync(user, this.CancellationToken);
}

这里我们写了 两个接口:
第一个:看参数很明显,这个是需要带着密码来创建的,里面校验了一些基本信息,其中validatePassword就是设置是否按照设定的密码规则进行校验。

Configure<IdentityOptions>(options =>
{
    options.User.RequireUniqueEmail = false;
    options.User.AllowedUserNameCharacters = "";
    options.Password.RequireDigit = false;
    options.Password.RequireLowercase = false;
    options.Password.RequireUppercase = false;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequiredLength = 8;
});
这段代码的配置可以放在api.host的module里,用来配置密码、邮箱、还有用户名格式的限制。
 options.User.AllowedUserNameCharacters = "";特殊说明一下,设置为空后,用户名就可以任意写了,否则abp有个默认的字符集限制,“abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+”,也就是你的用户名只能从这些字符里选,否则校验就会失败。

第二个:这个里面就什么校验都没有了。
更新用户

/// <summary>
/// Updates the specified <paramref name="user" /> in the backing store.
/// </summary>
/// <param name="user">The user to update.</param>
/// <returns>
/// The <see cref="T:System.Threading.Tasks.Task" /> that represents the asynchronous operation, containing the <see cref="T:Microsoft.AspNetCore.Identity.IdentityResult" />
/// of the operation.
/// </returns>
public override async Task<IdentityResult> UpdateAsync(IdentityUser user)
{
    this.ThrowIfDisposed();
    if(user==null)
    {
        throw new ArgumentNullException(nameof (user));
    }
    
    await this.UpdateNormalizedUserNameAsync(user);
    await this.UpdateNormalizedEmailAsync(user);
    return await this.Store.UpdateAsync(user, this.CancellationToken);
}

public async Task<IdentityResult> SetPasswordHashAsync(IdentityUser user,string password, bool validatePassword = false)
{
    return await UpdatePasswordHash(user, password, validatePassword);
}

这里有两个方法:
第一个:更新用户信息。
第二个:更新用户的密码。
这里单独更新密码,也是因为更新用户信息不一定就更新密码,所以预留个接口,需要的时候调用即可。

2.体验效果
写完后我们体验一下使用效果,随便写个service,注入我们写的UserManager:
我写了三个简单的方法:

public async Task<IdentityUser> GetUserByNameAsync(string userName)
{
    var user =await _userManager.FindByNameAsync(userName);
    return user;
}

public async Task<IdentityResult> CreateUserAsync(string userName, string password,string phoneNumber)
{
    var user = new IdentityUser(Guid.NewGuid(), userName,$"{userName}@bookstore.com");
    user.SetPhoneNumber(phoneNumber,true);
    
    return await _userManager.CreateAsync(user, "bookStore12345..");
}

public async Task<IdentityResult> UpdateUserAsync(Guid userId,string userName, string password,string phoneNumber)
{
    var user = await _userManager.FindByIdAsync(userId.ToString());
    user.SetPhoneNumber(phoneNumber,true);
    await _userManager.SetUserNameAsync(user, userName);
    await _userManager.SetPasswordHashAsync(user, password);
    return await _userManager.UpdateAsync(user);
}

调用创建方法:
在这里插入图片描述
完全相同的参数,我们这里调用了两次,都是成功。
在这里插入图片描述
数据库的记录也是有相同用户名的两条。创建没有问题,我们试下更新。

如果相同用户名的有多条,那么调用userManager.FindByNameAsync方法时会报错吗?如果不报错那么会返回哪条记录呢?下面看下调用效果。下面图中的效果是我调用接口10次返回的同样一个结果,都是最早创建的那个用户。
这里创建和修改时的用户名重复校验取消后,我们尽量就不要再去调用FindByNameAsync方法了,虽然它不报错,但是返回的是默认第一个创建的这个用户名的用户。

在这里插入图片描述
调用更新方法:
在这里插入图片描述
在这里插入图片描述
更新需要传入id,这里我们调用了两次,都成功了。看下数据库效果:
在这里插入图片描述
没有什么问题,更新成功了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨中深巷的油纸伞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值