【问题标题】:ASP.NET Identity custom UserStore with identity key带有身份密钥的 ASP.NET Identity 自定义 UserStore
【发布时间】:2014-06-01 04:03:05
【问题描述】:

我正在尝试实现一个自定义 UserStore,它将 ASP.NET 身份映射到现有的(而且相当复杂的)数据库模型。数据库有一个我想用来存储用户数据的现有表“联系人”。该表有一个 int identity(1,1) 主键。所以我创建了一个名为“ContactUser”的类来实现 IUser 和一个“ContactUserStore”来实现 IUserStore。基本登录现在可以使用了。

但是,我无法让新用户注册工作。当我尝试这样做时:

IdentityResult result = await UserManager.CreateAsync(user, model.Password);

它报错并抱怨找不到用户 ID。

这是因为 AspNet Identity 在调用 ContactUserStore.CreateAsync(ContactUser user) 时不知道在数据库中创建的联系人记录的身份密钥。该方法成功完成(创建联系人记录),但随后它使用 userId = 0 调用 ContactUserStore.FindByIdAsync(int userId),这不是它刚刚创建的用户...

有没有办法传回在 CreateAsync() 中在数据库中创建的 userId 的 @@identity 值?还是强制它在创建后使用 FindByName() 或 FindByEmail() 方法来选择用户?

【问题讨论】:

    标签: asp.net-identity asp.net-identity-2


    【解决方案1】:

    我自己解决了这个问题。必须反映 Microsoft.AspNet.Identity.Core 程序集以了解发生了什么以及如何修复它。

    事实证明,问题实际上发生在由 SignIn() 调用的 ClaimsIdentityFactory 中。该函数接收具有未初始化 ID 的用户对象,然后执行 UserStore.FindByIdAsync()。我必须做的是对 ClaimsIdentityFactory 进行子类化,重写 CreateAsync,并检查 Id=0 条件。在这种情况下,我会执行 FindByName 来获取 Id。我仍然更喜欢使用@@identity 来获取 ID,但现在,这可行。

    我提出了我的(未经彻底测试)code on github here,以防有人对它感兴趣(使用 Micro ORM 的自定义身份提供者)

    【讨论】:

    • 在 ClaimsIdentityFactory.CreateAsync - 为什么你的方法 sig 为: public override async Task CreateAsync(UserManager manager, ContactUser user, string authenticationType) ? ReSharper 报告说没有适合覆盖的东西 - 是否需要“覆盖”?
    【解决方案2】:

    您是否为您的 DbContext 映射了 OnModelCreating 中的键?

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            var user = modelBuilder.Entity<TUser>()
                .HasKey(u => u.ContactId)
    

    【讨论】:

    • 我不使用EntityFramework;我已经使用 Insight.Database 实现了提供程序,这是一个微组织
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 2016-12-31
    • 2022-11-27
    • 2019-01-23
    相关资源
    最近更新 更多