36

I am new to the ASP.NET Identity framework and am trying to do some things that I used to do in the older FormsAuthentication framework.

What I want to do is allow an administrative user to create a new user using the existing Register view (or similar) from within the app. Once this is complete, I would like to relationally associate that user (possibly using the ID that is generated) to other areas of the system.

How do I get access to the ID that is generated when calling UserManager.CreateAsync()?

EDIT: I am wanting existing users with "administrative" roles to create users from within the system in a User Management area. The answers below so far have explained how to get the ID for the "current" user which is not what I am looking for.

FrankO
  • 2,522
  • 6
  • 24
  • 34

6 Answers6

35

Using the IdentityUser or using a class that inherits from IdentityUser, makes the model having an UserId attribute. Using following code, passing the user to the method, will fill up the Id.

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

if (result.Succeeded)
    result = UserManager.AddToRole(user.Id, "User");

The model.GetUser() returns an object of the ApplicationUser or IdentityUser

public ApplicationUser GetUser()
{
    var user = new ApplicationUser
    {
        UserName = UserName,
        FirstName = FirstName,
        LastName = LastName,
        Email = Email,
        ...
    };

    return user;
}
Amirhossein Mehrvarzi
  • 18,024
  • 7
  • 45
  • 70
Jelle Oosterbosch
  • 1,731
  • 15
  • 17
  • I dont see where I get the ID of the user that was just created. Does the CreateAsync() method populate the 'user' parameter? – FrankO Jan 27 '14 at 15:47
  • And it populates the fields of IdentityUser which has the id field. – Jelle Oosterbosch Jan 28 '14 at 08:16
  • 1
    Thanks. This is what I was looking for. A way to get the data of a recently created user when created by another user from within the system. – FrankO Jan 28 '14 at 16:19
22

The accepted answer was not clear to me so I thought I would share this.

If you look at the source for the IdentityUser class you will find the following.

public class IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
{
    /// <summary>
    ///     Constructor which creates a new Guid for the Id
    /// </summary>
    public IdentityUser()
    {
        this.Id = Guid.NewGuid().ToString();
    }
    ... code omitted
}

As you can see, when creating a new IdentityUser instance the constructor generates a new GUID and populates the Id field.

This means if you create a new instance of a derived class such as ApplicationUser a new Id will still automatically be generated for you.

So, after you check that the user has been successfully added you can safely use the Id in the ApplicationUser class for your data association.

Example.

var user = new ApplicationUser
{
    UserName = "franko",
    FirstName = "Frank",
    LastName = "Ouimette",
    Email = "franko@emailservice.com"
};

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

if (result.Succeeded){
    result = UserManager.AddToRole(user.Id, "User");

    // User added successfully, you can safely use the Id now.
    var id = user.Id;

}
matt.
  • 2,355
  • 5
  • 32
  • 43
8

What worked for me was something slightly different:

var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var user = new ApplicationUser() { Email = "informatyka4444@wp.pl", UserName = "informatyka4444@wp.pl" };
var result = manager.Create(user, "TestPass44!");

if (result.Succeeded)
{
    string newId = user.Id;
}
Fernando Vezzali
  • 2,219
  • 1
  • 29
  • 32
  • Thanks Fernando this solution fits better for my use case (we use email's as username and have more manual control over the user management process) – Trevor Jul 04 '16 at 13:36
4

Some extension methods have been added to the Identity framework, including this one:

public static string GetUserId(this IIdentity identity);

After performing the sign-in, you should be able to retrieve the ID easily enough:

await SignInAsync(user, isPersistent: false);
var id = this.User.Identity.GetUserId()
Mister Epic
  • 16,295
  • 13
  • 76
  • 147
  • 2
    Wont that give me the ID of the current user? I want the ID that the current user created when adding another user. – FrankO Jan 27 '14 at 04:10
  • @FrankO, if the `GetUserId` method takes an `IIdentity` (a user) as a parameter, why wouldn't it give you the ID of *that* user? – bzlm Aug 18 '15 at 06:41
1

This thread is already a few years old, but I encountered this problem and needed to find another solution because I do not use the provided Guids, but a standard integer ID, provided by the database (auto-incremented index).

The problem that I had was that if I created the user with UserManager.CreateAsync, the user object wasn't updated with the ID. I then created a related object for that user, and since the ID wasn't updated, Entity Framework tried to save the user to the database another time which resulted in a primary key violation.

To solve the problem, I needed to read/update the user object like so:

var user = new User
{
    UserName = UserName,
    FirstName = FirstName,
    LastName = LastName,
    Email = Email,
    ...
};

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

// At this point, the user has been created, but the ID not set

// Read the full user record from the database
user = db.Users.Where(u => u.Email == user.Email).FirstOrDefault();

// At this point, the user has the correct ID set, we are good to go...
embee
  • 21
  • 2
  • Is your User object inheriting from the IdentityUser? – FrankO Feb 11 '17 at 00:23
  • No, my User class implements the `IUser` interface. – embee Feb 11 '17 at 17:47
  • Seems odd that the ID is not being populated. Have you tried inheriting from IdentityUser? – FrankO Feb 14 '17 at 01:12
  • I agree, it's surprising behaviour. I have made this decision two years ago, but I think I used the `iUser` interface because I use a database-first approach. It allowed me to independently model the user entity in the database. After I imported my data model, I created a partial class for the User entity that inherits the bespoke interface, so that I can plug it into my user manager. – embee Feb 20 '17 at 14:03
-3

In the event for user created, add:

string user = RegisterUser.UserName; or to use later 
Session["user"] = RegisterUser.UserName;
arserbin3
  • 6,010
  • 8
  • 36
  • 52