如何使用ASP.NET Identity创建用户并获取新创建的ID

37

我对ASP.NET Identity框架还很新,正在尝试做一些以前在旧的FormsAuthentication框架中常做的事情。

我想做的是允许管理员用户使用现有的注册视图(或类似视图)从应用程序内部创建新用户。完成后,我想将该用户关联到系统的其他区域(可能使用生成的ID)。

我如何获取调用UserManager.CreateAsync()时生成的ID?

编辑:我希望具有“管理”角色的现有用户能够从用户管理区域在系统内创建用户。迄今为止,下面的答案已经解释了如何获取“当前”用户的ID,但这不是我要找的。

6个回答

36

使用 IdentityUser 或者继承自 IdentityUser 的类,使得模型具有一个 UserId 属性。使用下面的代码,将用户传递给方法,将填充 Id。

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

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

model.GetUser()返回一个ApplicationUserIdentityUser对象。

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

    return user;
}

我看不到刚刚创建的用户的ID在哪里。CreateAsync()方法是否会填充'user'参数? - FrankO
它填充了具有id字段的IdentityUser的字段。 - Jelle Oosterbosch
1
谢谢。这正是我在寻找的。一种从系统内部获取由另一个用户创建的最近创建的用户数据的方法。 - FrankO

22

因为我对被接受的答案不太清楚,所以我想分享一下这个。

如果你查看IdentityUser类的源代码,你会发现以下内容。

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
}

正如您所看到的,当创建一个新的IdentityUser实例时,构造函数会生成一个新的GUID并填充Id字段。

这意味着如果您创建了一个派生类的新实例,例如ApplicationUser,那么一个新的Id仍将自动生成。

因此,在您检查用户已被成功添加之后,您可以安全地在ApplicationUser类中使用该Id进行数据关联。

例如。

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;

}

8
我对此的理解有些不同:我的方法略有不同。
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,这个解决方案更适合我的用例(我们使用电子邮件作为用户名,并对用户管理过程有更多手动控制)。 - Trevor

4

Identity框架添加了一些扩展方法,包括这个:

public static string GetUserId(this IIdentity identity);

在完成登录后,您应该能够很容易地检索到ID:

await SignInAsync(user, isPersistent: false);
var id = this.User.Identity.GetUserId()

2
那不会给我当前用户的ID吗?我想要当前用户在添加另一个用户时创建的ID。 - FrankO
@FrankO,如果GetUserId方法以IIdentity(用户)作为参数,为什么它不会给你那个用户的ID呢? - bzlm

1
这个帖子已经几年了,但我遇到了这个问题,需要找到另一个解决方案,因为我不使用提供的Guids,而是使用数据库提供的标准整数ID(自动递增索引)。
我的问题是,如果我使用UserManager.CreateAsync创建用户,则用户对象不会更新ID。然后,我为该用户创建了一个相关对象,由于ID未更新,Entity Framework尝试再次将用户保存到数据库中,导致主键冲突。
为了解决这个问题,我需要像这样读取/更新用户对象:
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...

你的User对象是否继承自IdentityUser? - FrankO
不,我的User类实现了IUser<int>接口。 - embee
看起来很奇怪,ID没有被填充。你尝试过从IdentityUser继承吗? - FrankO
我同意,这是令人惊讶的行为。两年前我做出了这个决定,但我认为我使用了iUser接口,因为我采用了数据库优先的方法。它使我能够独立地在数据库中建模用户实体。在导入我的数据模型后,我为用户实体创建了一个部分类,该部分类继承了定制接口,以便我可以将其插入到我的用户管理器中。 - embee

-3

对于用户创建事件,添加:

string user = RegisterUser.UserName; or to use later 
Session["user"] = RegisterUser.UserName;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接