自定义身份用户和扩展配置文件 MVC

Posted

技术标签:

【中文标题】自定义身份用户和扩展配置文件 MVC【英文标题】:custom identity user and extending profile 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 我遇到了身份框架问题 【参考方案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 中创建一个属性并按需获取配置文件数据。我不想改变它,因为我用过很多地方。我将在新项目或我的任何示例项目中按照您的方法进行测试。

以上是关于自定义身份用户和扩展配置文件 MVC的主要内容,如果未能解决你的问题,请参考以下文章

自定义配置文件提供程序:未找到设置属性“”-MVC3

23用户自定义扩展功能实现

abp.io - 扩展用户配置文件

Django 重写用户模型

扩展 satchmo 用户配置文件

Spring Boot中Spring MVC的整合支持