【问题标题】:IUserStore<TUser>.CreateAsync : how to indicate failure in custom implementation?IUserStore<TUser>.CreateAsync :如何在自定义实现中指示失败?
【发布时间】:2015-10-03 21:16:04
【问题描述】:

我正在为 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,因为商店中的返回类型只是“任务”。我有一个自定义逻辑来确定是否可以创建用户,所以我真的需要将 CreateAsync 的结果告诉 UserManager。

有什么想法吗?

【问题讨论】:

  • 在您的应用程序流程中,当无法创建用户时,这是例外情况还是正常执行流程的一部分?
  • @YuvalItzchakov 感谢您的关注!它是正常执行流程的一部分。为了提供更多上下文,我在不同的程序集中对 ASP.Identity 进行自定义实现,这就是为什么我想直接在 UserStore 中处理这种情况以使客户端专注于业务逻辑

标签: c# asp.net-mvc asp.net-identity


【解决方案1】:

查看source code for UserManager.CreateAsync(这是针对Identity 2.0)可以看到,在调用IUserStore.CreateAsync之前,它调用了IIdentityValidator&lt;TUser&gt;.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&lt;TUser&gt; 并将其设置在您的 UserManager 实例上。

【讨论】:

  • 啊哈,我们是在同一时间发布的!感谢您的帮助,我一定会看看 IUserValidator
  • @red2nb 我还浏览了 GitHub 上的源代码,然后注意到它是针对 ASP.NET 5 的。所以我转而查看了 SymbolSource。接口其实叫IIdentityValidator&lt;TUser&gt;,我已经更新了答案
  • 其实还是有问题的。我正在做的验证是完整性检查。通过依赖 UserValidator,我缺少调用此 Validator 的上下文(创建、更新等)。我猜这个验证器主要是用来检查属性是否已经设置以及这类事情。
  • 我只是把检查放在客户端,让我们在设计上妥协。我将在那里创建一个临时扩展方法,非常感谢您的帮助
  • 你能帮我解决这个问题吗:stackoverflow.com/questions/39275597/…
【解决方案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;
    }

所以基本上它们总是返回 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 中是可能的。在我看来,这将是一种更好的设计,因为客户不必处理完整性问题。

【讨论】:

  • 所以基本上它们总是返回 true。 如果你再看一下代码,你会发现如果对 ValidateAsync 的调用返回的不是成功,那么它就是IdentityResult 将返回其中包含错误。所以它实际上并不总是返回 true。
  • 你能帮我解决这个问题吗:stackoverflow.com/questions/39275597/…
猜你喜欢
  • 2016-10-06
  • 2015-08-03
  • 2011-09-21
  • 2018-11-05
  • 1970-01-01
  • 1970-01-01
  • 2021-03-29
  • 2022-10-04
  • 2017-10-10
相关资源
最近更新 更多