自定义标识用户和扩展配置文件MVC

时间:2015-05-04 12:06:29

标签: c# asp.net-mvc entity-framework asp.net-mvc-5 asp.net-identity

我正在尝试将身份用户数据扩展到单独的表中,但它没有填充。

  public class MyUserInfo
  {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

  }

  public class AppUser : IdentityUser<Int32, AppUserLogin, AppUserRole, AppUserClaim>
  {

    public MyUserInfo MyUserInfo { get; set; }
 }

//Fetching the user data

var userStore = new UserStore<AppUser, AppRole, int, AppUserLogin, AppUserRole, AppUserClaim>(db);
var userManager = new UserManager<AppUser, int>(userStore);

var user = userManager.FindById(1);

user.MyUserInfo 显示null。但在db中,我们有各自的用户数据。

我看到许多帖子没有自定义似乎有效但对我来说我修改了存储为整数的id并更改了表名。

2 个答案:

答案 0 :(得分:6)

股票 Identity UserManager 不会自动提取UserInfo(或任何其他具有外键导航的表实体)

您已扩展身份架构,但尚未扩展 UserManager

用于获取用户(例如findbyid()FindByIdAsync())的 UserManager 的方法无法通过实体框架导航检索“子”实体。

查看 GitHub FindByIdAsync

    public virtual Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))
    {
        cancellationToken.ThrowIfCancellationRequested();
        ThrowIfDisposed();
        var id = ConvertIdFromString(userId);
        return Users.FirstOrDefaultAsync(u => u.Id.Equals(id), cancellationToken);
    }

该方法仅返回用户实体。没有检查“子”导航表的功能,更不用说拉它们了。

您可以通过实施此类方法来扩展 UserManager

否则,您必须在检索UserId后手动拉取子实体。我就这样做了:

            var UserId = User.Identity.GetUserId<int>();

            try
            {
                user = await UserManager.FindByIdAsync(UserId );
            }
            catch (Exception e)
            {
                return BadRequest(e.Message);
            }

            var userInfo = AuthContext.UserInfo.
                   FirstOrDefault(u => u.Id == user.UserInfo_Id);

注意:我还必须确保我的ApplicationUser实体UserInfo有一个外键:

public class ApplicationUser : IdentityUser
{
    [ForeignKey("UserInfo")]
    public int UserInfo_Id { get; set; }

    public virtual UserInfo UserInfo { get; set; }

和我的模型构建器

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ApplicationUser>()
          .HasRequired<UserInfo>(profile => profile.UserInfo);


        base.OnModelCreating(modelBuilder);
    }

答案 1 :(得分:2)

我认为这里的问题不是严格关于asp.net身份,而是关于实体框架。 由于您从userManager.FindById(1)获取数据,但是您没有从MyUserInfo表中获取相关数据,因此该关系不存在。

MyUserInfo实体更改为

public class MyUserInfo
{
    //change it from Id to AppUserId
    public int AppUserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }   
    //add this virtual property
    public virtual AppUser User { get; set; }
}

然后添加迁移并更新数据库。实体框架将使表和AppUserId之间的关系成为外键(代码优先关系约定)。