Reputation: 1951
I am trying to implement a custom UserStore that maps ASP.NET Identity to an existing (and rather convoluted) database model. The database has an existing table 'Contact' that I want to use to store user data. That table has an int identity(1,1) primary key. So I have created a class named 'ContactUser' that implements IUser and a 'ContactUserStore' that implements IUserStore. The basic login now works.
However, I can't get new user registration to work. When I try to do:
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
it bombs with an error complaining that it can't find the userId.
That is caused by the fact that AspNet Identity does not know the identity key of the Contact record that was created in the database when it called ContactUserStore.CreateAsync(ContactUser user). That method completes succesfully (creating a Contact record), but then it calls into ContactUserStore.FindByIdAsync(int userId) with a userId = 0, which is not the user it just created...
Is there a way to pass back the @@identity value of the userId that was created in the database in CreateAsync()? Or force it to use the FindByName() or FindByEmail() methods to select the user after creation?
Upvotes: 0
Views: 1867
Reputation: 1951
I have solved the problem myself. Had to reflect the Microsoft.AspNet.Identity.Core assembly to understand what was happening and how to fix it.
It turned out that the problem was actually happening in ClaimsIdentityFactory, that was called by SignIn(). That function receives the user object with the uninitialized Id, and then does UserStore.FindByIdAsync(). What I had to do was subclass the ClaimsIdentityFactory, override CreateAsync, and check for the Id=0 condition. In that case I do a FindByName to get the Id. I'd still prefer to use @@identity to get the Id, but for now, this works.
I put up my (not thoroughly tested) code on github here in case anyone is interested in it (a custom identity provider using a Micro ORM)
Upvotes: 2
Reputation: 28200
Did you map the key in OnModelCreating for your DbContext?
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var user = modelBuilder.Entity<TUser>()
.HasKey(u => u.ContactId)
Upvotes: 1