IUserStore< TUser>.CreateAsync:如何在自定义实现中指示失败
本文关键字:自定义 实现 失败 指示 TUser CreateAsync IUserStore | 更新日期: 2023-09-27 18:15:56
我正在为IUserStore编写一个自定义实现。create方法的签名是:
public async virtual Task CreateAsync(TUser user)
考虑到Microsoft.AspNet.Identity的核心接口IUserStore是(这是相同的),这是有意义的。
然而,在Microsoft.AspNet.Identity中定义的UserManager类的接口是:
public virtual Task<IdentityResult> CreateAsync(TUser user);
我的问题是我不知道我应该如何将这个IdentityResult传递给UserManager,因为在商店中的返回类型只是"任务"。我有一个自定义逻辑来确定是否可以创建一个用户,所以我真的需要告诉UserManager CreateAsync的结果。
查看UserManager.CreateAsync
的源代码(这是Identity 2.0),您可以看到在调用IUserStore.CreateAsync
之前,它会调用IIdentityValidator<TUser>.ValidateAsync
,它负责实际返回相关的IdentityResult
对象:
public virtual async Task<IdentityResult> CreateAsync(TUser user)
{
ThrowIfDisposed();
await UpdateSecurityStampInternal(user).ConfigureAwait(false);
var result = await UserValidator.ValidateAsync(user).ConfigureAwait(false);
if (!result.Succeeded)
{
return result;
}
if (UserLockoutEnabledByDefault && SupportsUserLockout)
{
await GetUserLockoutStore().SetLockoutEnabledAsync(user, true).ConfigureAwait(false);
}
await Store.CreateAsync(user).ConfigureAwait(false);
return IdentityResult.Success;
}
IUserStore.CreateAsync
的主要目的是调用保存数据的底层数据源。似乎你实际上想要实现IIdentityValidator<TUser>
并将其设置在你的UserManager
实例上。
答案在源代码中,这是在撰写本文时UserManager中实现的一部分:
public virtual async Task<IdentityResult> CreateAsync(TUser user,
CancellationToken cancellationToken = default(CancellationToken))
{
ThrowIfDisposed();
await UpdateSecurityStampInternal(user, cancellationToken);
var result = await ValidateUserInternal(user, cancellationToken);
if (!result.Succeeded)
{
return result;
}
if (Options.Lockout.EnabledByDefault && SupportsUserLockout)
{
await GetUserLockoutStore().SetLockoutEnabledAsync(user, true, cancellationToken);
}
await UpdateNormalizedUserNameAsync(user, cancellationToken);
await Store.CreateAsync(user, cancellationToken);
return IdentityResult.Success;
}
基本上它们总是返回true。这意味着在当前版本中,将我的创建检查放在UserStore中违背了框架的预期用途。
然而,我已经注意到这将在下一个版本中改变。IUserStore接口将变成:
Task<IdentityResult> CreateAsync(TUser user, CancellationToken cancellationToken);
和UserManager的实现:
public virtual async Task<IdentityResult> CreateAsync(TUser user)
{
ThrowIfDisposed();
await UpdateSecurityStampInternal(user);
var result = await ValidateUserInternal(user);
if (!result.Succeeded)
{
return result;
}
if (Options.Lockout.AllowedForNewUsers && SupportsUserLockout)
{
await GetUserLockoutStore().SetLockoutEnabledAsync(user, true, CancellationToken);
}
await UpdateNormalizedUserNameAsync(user);
await UpdateNormalizedEmailAsync(user);
return await Store.CreateAsync(user, CancellationToken);
}
因此,将创建逻辑放在UserStore中是可能的。在我看来,这将是一种更好的设计方式,因为客户端不应该处理完整性问题。