IUserStore<TUser>.CreateAsync :如何指示自定义实现失败?
IUserStore<TUser>.CreateAsync : how to indicate failure in custom implementation?
我正在为 IUserStore 编写自定义实现。 create方法的签名是:
public async virtual Task CreateAsync(TUser user)
考虑到 Microsoft.AspNet.Identity 中的核心接口 IUserStore 是(相同的),这是有道理的。
但是 Microsoft.AspNet.Identity 中定义的 UserManager class 的接口是:
public virtual Task<IdentityResult> CreateAsync(TUser user);
我的问题是我不知道如何将此 IdentityResult 传递给 UserManager,因为商店中的 return 类型只是 "Task"。我有一个自定义逻辑来确定是否可以创建用户,所以我确实需要将 CreateAsync 的结果告诉 UserManager。
有什么想法吗?
答案是 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;
}
所以基本上他们总是 return 正确。这意味着在当前版本中,将我的创建检查放在 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中就可以了。在我看来,这将是一种更好的设计方式,因为客户不必处理完整性问题。
查看 source code for UserManager.CreateAsync
(这是针对 Identity 2.0),您可以看到在调用 IUserStore.CreateAsync
之前,它会调用 IIdentityValidator<TUser>.ValidateAsync
,它实际上负责 return 相关 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
实例上。
我正在为 IUserStore 编写自定义实现。 create方法的签名是:
public async virtual Task CreateAsync(TUser user)
考虑到 Microsoft.AspNet.Identity 中的核心接口 IUserStore 是(相同的),这是有道理的。
但是 Microsoft.AspNet.Identity 中定义的 UserManager class 的接口是:
public virtual Task<IdentityResult> CreateAsync(TUser user);
我的问题是我不知道如何将此 IdentityResult 传递给 UserManager,因为商店中的 return 类型只是 "Task"。我有一个自定义逻辑来确定是否可以创建用户,所以我确实需要将 CreateAsync 的结果告诉 UserManager。
有什么想法吗?
答案是 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;
}
所以基本上他们总是 return 正确。这意味着在当前版本中,将我的创建检查放在 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中就可以了。在我看来,这将是一种更好的设计方式,因为客户不必处理完整性问题。
查看 source code for UserManager.CreateAsync
(这是针对 Identity 2.0),您可以看到在调用 IUserStore.CreateAsync
之前,它会调用 IIdentityValidator<TUser>.ValidateAsync
,它实际上负责 return 相关 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
实例上。