【问题标题】:custom identity user and extending profile MVC自定义身份用户和扩展配置文件 MVC
【发布时间】:2015-07-13 19:35:07
【问题描述】:

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

  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 并更改了表名。

【问题讨论】:

  • 这都是相关代码吗?导致实体框架不会在这样的表之间建立任何关系
  • 这不是那么简单...但是您可以轻松地创建一个与您现有的表等相匹配的 CustomMembershipProvider。这是值得的,恕我直言。 logcorner.wordpress.com/2013/08/29/…
  • @Robert 你说的是旧的MembershipProvider,问题是关于新的身份框架,这些不一样。
  • @tmg 我只粘贴了 appUser 和 Profile 其余表的代码,例如角色等。一切正常。 MyUserInfo 数据未填充。见参考文献。 blogs.msdn.com/b/webdev/archive/2013/10/16/…
  • @Robert 我遇到了身份框架问题

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


【解决方案1】:

我认为这里的问题不是严格意义上的 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 将是外键(代码优先关系约定)。

【讨论】:

  • 我之前的假设是相同的,但迁移时出错:“无法确定类型‘App.Data.Entities.AppUser’和‘App.Data.Entities.MyUserInfo’之间关联的主体端'。必须使用关系流式 API 或数据注释显式配置此关联的主体端。"
  • 其原因实体框架无法确定哪个 MyUserInfo.Id 或 AppUser.Id 是主键,哪个是外键,您是否像我一样尝试重命名?
  • 我试过 public class MyUserInfo { [Key, ForeignKey("User")] public int AppUserId { get;放; } 公共字符串名字 { 获取;放; } 公共字符串姓氏 { 获取;放; } 公共虚拟 AppUser 用户 { 获取;放; } }
【解决方案2】:

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

您已扩展 Identity Schema,但尚未扩展 UserManager

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

看看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);
    }

【讨论】:

  • 我同意你的看法。 UserManager 不会自动拉取 MyUserInfo。但我认为您需要将 User.Identity.GetUserId() 更改为 User.Identity.GetUserId() 因为 pk 是 int。
  • @DaveAlperovich 首先非常感谢您抽出宝贵的时间。是的,我读了你的答案并做同样的事情。但我担心它应该按照这个 ms 博客 blogs.msdn.com/b/webdev/archive/2013/10/16/… 自动填充。无论如何,作为您的建议,在定制的情况下不应该这么多。再次感谢您的光临。
  • @Parwej,我之前没注意到你在说什么。那篇文章不准确。如果您查看 GitHub 上的源代码,您会发现该方法只是返回用户实体return Users.FirstOrDefaultAsync(u =&gt; u.Id.Equals(id), cancellationToken);github.com/aspnet/Identity/blob/dev/src/…
  • @Parwej,我理解您的困惑并更新了我的答案。我不明白为什么 MSDN 会发布如此明显错误的内容。我希望这能更好地解释。
  • @DaveAlperovich 现在,我只是在 AppUser 中创建一个属性并按需获取配置文件数据。我不想改变它,因为我用过很多地方。我将在新项目或我的任何示例项目中按照您的方法进行测试。
猜你喜欢
  • 2014-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2021-12-30
  • 2012-03-11
相关资源
最近更新 更多