Flow Of UserManager.CreateAsync

Oct 22, 2014 at 10:39 PM
I have a personalized user database that I'm using with an custom userstore that implements all the relevant interfaces.
I'm having trouble adding a new user and can't seem to get my head around the flow.
When I call create Async it hashes the password and calls SetPasswordHashAsync, then SetSecurityStampAsync, twice, then it tries to get the user based on EmailAddress and finally returns.
In all this flow it never runs CreateAsync in the user store. This is where I would expect to add a user to the database and until this is done I can't update the password or securitystamp.
I'm thinking it's probably best if I skip the user manager entirely for this but my only issue is I won't then set the SecurityStamp,
Will this be a problem or am I looking at this in the wrong way?

As an addidtional bit of info I am not using entity framework at all. I don't have unrestricted access to the DB so everything goes through a helper repository via the UserStore.
Developer
Nov 15, 2014 at 2:29 AM
What is the IdentityResult returned ? Are there any errrors ? If the user is not being created then some validation might be failing.
Dec 27, 2014 at 7:20 AM
I'm getting the exact same problem here - I've ditched the entity framework and written my own database access methods. I've followed this:

http://www.asp.net/identity/overview/extensibility/overview-of-custom-storage-providers-for-aspnet-identity

The issue that I get is that the call to UserManager.CreateAsync(user, model.password) fails. It also seems to make the same nonsensical calls to SetPasswordHashAsync, etc. I'd really like to see the internals of what CreateAsync is actually doing. At this point I'm completely stuck. Despite being 100% sure that the values being passed into CreateAsync are valid, it's failing, and brings back a very generic "Email must not be null or empty" message.
Dec 28, 2014 at 7:18 PM
Probably not the most helpful answer but I ended up completely bypassing the user manger for creating a user. In the controller I first check the password with a PasswordValidator e.g. something like
// Check Password
                var passwordValidate = new PasswordValidator
                {
                    RequiredLength = 6,
                    RequireNonLetterOrDigit = true,
                    RequireDigit = true,
                    RequireLowercase = true,
                    RequireUppercase = true,
                };

                var passResult = await passwordValidate.ValidateAsync(model.Password);
                if (!passResult.Succeeded)
                {
                    valid = false;
                    AddErrors(passResult);
                }
Then I check username , email address and display name doesn't exist and finally if all is ok I hash the password and manually insert the entry into the user database. In my case I'm using email confirmation so at the end of the method I fire off an email to the user to activate their account.
Feb 1, 2015 at 1:34 PM
Edited Feb 1, 2015 at 1:35 PM
The reason why it fails is because the method it's messed up! I spent 2 hours trying to understand why I got those error, it didn't make any sense to me.

UserManager.cs contents

If you open the link above you will see the contents of the UserManager.cs. It becomes clear that the method it's doing the wrong thing. So first is updating the user password in the database and then creates the user. I mean ... how the hell is that even LOGIC :)
Feb 2, 2015 at 3:52 PM
scuty: I think I figured it out!

In the user store, you don't actually need to make database calls to update your custom User. All you need to do is set the properties on the user. Then, when the call is made to your UserStore to create a new user, you update every single field on the user. This means that you aren't actually making any database calls until your user is created. It took me a bit to figure that out!
Feb 2, 2015 at 4:35 PM
Good point!