正在将详细信息表读取到ASP.NET MVC 5 Identity 2

本文关键字:MVC NET Identity ASP 详细信息 读取 | 更新日期: 2023-09-27 18:13:55

我想让我的IdentityUser派生类引用细节表上的一些数据。为了做到这一点,我创建了一个扩展的IdentityUser,它引用了一个外部详细信息表,并相应地配置了IdentityDbContext,以便创建相应的表。

public class ApplicationUser : IdentityUser
{
    public ICollection<PublishingContext> PublishingContexts { get; set; }
    public ApplicationUser()
    {
        PublishingContexts = new List<PublishingContext>();
    }
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}
public class PublishingContext
{
    public string UserId { get; set; }
    public string Name { get; set; }
    public string Uri { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
    public virtual IDbSet<PublishingContext> PublishingContexts { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<ApplicationUser>()
            .HasMany(u => u.PublishingContexts).WithRequired().HasForeignKey(ul => ul.UserId);
        modelBuilder.Entity<PublishingContext>()
            .HasKey(c => new { c.UserId, c.Name });
    }
}

问题是,即使创建了PublishingContexts表,并且我手动在其中填充了一些数据,我也无法在登录时读取相应的值。我认为我需要在系统上的其他地方配置新表,但我目前陷入了困境。有什么建议吗?

正在将详细信息表读取到ASP.NET MVC 5 Identity 2

我想我想通了。您需要定义一个自定义UserStore,它将重新定义FindBy方法,包括相应的详细信息表。

public class ApplicationUserStore : UserStore<ApplicationUser>
{
    public ApplicationUserStore() : this(new IdentityDbContext())
    {
        DisposeContext = true;
    }
    public ApplicationUserStore(DbContext context) : base(context)
    {
    }
    public override Task<ApplicationUser> FindByIdAsync(string userId)
    {
        return GetUserAggregateAsync(u => u.Id.Equals(userId));
    }
    public override Task<ApplicationUser> FindByNameAsync(string userName)
    {
        return GetUserAggregateAsync(u => u.UserName.ToUpper() == userName.ToUpper());
    }
    Task<ApplicationUser> GetUserAggregateAsync(Expression<Func<ApplicationUser, bool>> filter)
    {
        return Users.Include(u => u.Roles)
            .Include(u => u.Claims)
            .Include(u => u.Logins)
            .Include(u => u.PublishingContexts)
            .FirstOrDefaultAsync(filter);
    }
}

这是直接从Identity 2来源获取的。基本上,我只是在GetUserAggregateSync方法上添加了.Include子句,我必须重新定义它,因为它在基类上是私有的。一旦你这样做了,你将不得不告诉系统使用你的用户存储,通过在App_Start 中的IdentityConfig.cs文件上更改它

var manager = new ApplicationUserManager(new ApplicationUserStore(
    context.Get<ApplicationDbContext>()));