为ABP新增手机验证模块之二
Posted 上将军
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为ABP新增手机验证模块之二相关的知识,希望对你有一定的参考价值。
在上一篇文章,实现了登录的验证,但没有实现实现在新增或编辑用户时将手机作为必填项,本文将完成这最后一步。
新增和编辑用户将手机作为必填项,这个没特别方法,只能使用新的页面覆盖旧的页面,这个和覆盖登录页面原来是一样的,就不详细说了。
接下来要做的是对手机进行验证了,这个也是比较简单的,只要添加一个自定义的用户验证就行了,具体代码如下:
public class PhoneLoginUserValidator : IUserValidator<IdentityUser>
public PhoneLoginUserValidator(PhoneLoginUserManager phoneLoginUserManager, IStringLocalizer<PhoneLoginResource> localizer)
PhoneLoginUserManager = phoneLoginUserManager;
Localizer = localizer;
protected PhoneLoginUserManager PhoneLoginUserManager get;
protected IStringLocalizer<PhoneLoginResource> Localizer get;
private async Task<List<IdentityError>?> ValidatePhone(IdentityUser user)
var phone = await PhoneLoginUserManager.GetPhoneNumberAsync(user).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(phone))
throw new InvalidPhoneNumberBusinessException(phone);
var owner = await PhoneLoginUserManager.FindByPhoneAsync(phone).ConfigureAwait(false);
if (owner != null &&
!string.Equals(await PhoneLoginUserManager.GetUserIdAsync(owner).ConfigureAwait(false), await PhoneLoginUserManager.GetUserIdAsync(user).ConfigureAwait(false)))
throw new DuplicatePhoneNumberBusinessException(phone);
return null;
public async Task<IdentityResult> ValidateAsync(UserManager<IdentityUser> manager, IdentityUser user)
if (user == null)
throw new ArgumentNullException(nameof(user));
var errors = await ValidatePhone(user).ConfigureAwait(false);
return errors?.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
自定义用户验证需继承自IUserValidator<IdentityUser>
接口,主要就是实现ValidateAsync
方法。
本来打算在验证到错误的时候按照原有格式返回IdentityError
的,但本地化问题解决不了,于是只能采用暴力方式直接抛出错误。
实现了验证类,下面要做的是通过AddUserValidator
方法将验证类添加到用户验证列表中,这个要在模块内类实现,代码如下:
public class GenericAbpPhoneLoginDomainModule : AbpModule
public override void PreConfigureServices(ServiceConfigurationContext context)
PreConfigure<IdentityBuilder>(builder =>
builder.AddUserValidator<PhoneLoginUserValidator>();
);
本以为这样就大功告成了,但测试时发现手机永远是空,这就奇怪了,然后看了IdentityUserAppService
的CreateAsync
方法才发现在调用UserManager
的CreateAsync
方法时,并没有将手机放到实体里,这就要重写改服务了。也是只能新建一个项目来实现这个方法,代码如下:
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService), typeof(PhoneLoginUserAppService))]
public class PhoneLoginUserAppService : IdentityUserAppService
public PhoneLoginUserAppService(IdentityUserManager userManager, IIdentityUserRepository userRepository, IIdentityRoleRepository roleRepository, IOptions<IdentityOptions> identityOptions) : base(userManager, userRepository, roleRepository, identityOptions)
public override async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
await IdentityOptions.SetAsync();
var user = new IdentityUser(
GuidGenerator.Create(),
input.UserName,
input.Email,
CurrentTenant.Id
);
user.SetPhoneNumber(input.PhoneNumber, false);
input.MapExtraPropertiesTo(user);
(await UserManager.CreateAsync(user, input.Password)).CheckErrors();
await UpdateUserByInput(user, input);
(await UserManager.UpdateAsync(user)).CheckErrors();
await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user);
代码不算复杂,就是过程复杂。
使用方法
- 在应用的
Application
模块引用Generic.Abp.PhoneLogin.Application
- 在应用的
Domain
模块引用Generic.Abp.PhoneLogin.Domain
- 在应用的
Web
模块引用Generic.Abp.PhoneLogin.Web
源代码:https://github.com/tianxiaode/GenericAbp
以上是关于为ABP新增手机验证模块之二的主要内容,如果未能解决你的问题,请参考以下文章
ABP Framework 5.2 RC 版本发布及新增功能介绍