我正在尝试实现一个自定义UserStore,它将ASP.NET Identity映射到现有(而且相当复杂的)数据库模型。数据库有一个现有的表'Contact',我想用它来存储用户数据。该表具有int identity(1,1)主键。所以我创建了一个名为'ContactUser'的类,它实现了IUser和一个实现IUserStore的'ContactUserStore'。基本登录现在有效。
但是,我无法让新的用户注册工作。当我尝试做的时候:
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
它抱怨错误,抱怨它无法找到userId。
这是因为AspNet Identity在调用ContactUserStore.CreateAsync(ContactUser用户)时不知道在数据库中创建的Contact记录的身份密钥。该方法成功完成(创建一个Contact记录),但随后它调用了ContactUserStore.FindByIdAsync(int userId),其userId = 0,而不是刚刚创建的用户......
有没有办法在CreateAsync()中传回在数据库中创建的userId的@@ identity值?或者强制它使用FindByName()或FindByEmail()方法在创建后选择用户?
答案 0 :(得分:2)
我自己解决了这个问题。不得不反映Microsoft.AspNet.Identity.Core程序集,以了解发生了什么以及如何解决它。
事实证明,问题实际上发生在由SignIn()调用的ClaimsIdentityFactory中。该函数接收具有未初始化Id的用户对象,然后执行UserStore.FindByIdAsync()。我必须做的是继承ClaimsIdentityFactory,覆盖CreateAsync,并检查Id = 0条件。在那种情况下,我做一个FindByName来获取Id。我仍然倾向于使用@@ identity来获取Id,但是现在,这有效。
我提出了我的(未经过全面测试)code on github here,以防任何人对此感兴趣(使用Micro ORM的自定义身份提供商)
答案 1 :(得分:1)
您是否在OnModelCreating中为您的DbContext映射了密钥?
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var user = modelBuilder.Entity<TUser>()
.HasKey(u => u.ContactId)