我正在为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,因为商店中的返回类型只是&#34;任务&#34;。我有一个自定义逻辑来确定是否可以创建用户,所以我真的需要将CreateAsync的结果告诉UserManager。
有什么想法吗?
答案 0 :(得分:4)
查看source code for 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
实例上。
答案 1 :(得分:2)
答案是in the source code,这是撰写本文时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;
}
所以基本上他们总是回归真实。这意味着在当前版本中,将我的创建检查放在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中。在我看来,这将是一种更好的设计,因为客户不应该处理完整性问题。