自定义身份用户和扩展配置文件 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.GetUserIdreturn Users.FirstOrDefaultAsync(u => u.Id.Equals(id), cancellationToken);
github.com/aspnet/Identity/blob/dev/src/…
@Parwej,我理解您的困惑并更新了我的答案。我不明白为什么 MSDN 会发布如此明显错误的内容。我希望这能更好地解释。
@DaveAlperovich 现在,我只是在 AppUser 中创建一个属性并按需获取配置文件数据。我不想改变它,因为我用过很多地方。我将在新项目或我的任何示例项目中按照您的方法进行测试。以上是关于自定义身份用户和扩展配置文件 MVC的主要内容,如果未能解决你的问题,请参考以下文章