ASP NET核心身份与实体框架自定义DbContext

时间:2017-03-28 20:52:24

标签: asp.net-core entity-framework-core asp.net-core-identity

我已经尝试阅读ASP.NET核心身份和实体框架上的文档。但我觉得还不是更聪明。

我不想与IdentityDbContextIdentityUserIdentityRole有任何关系。我只想使用自己的DbContext实施,并与UserManagerUserStoreRoleManagerSignInManager以及登录所涉及的其他课程一起愉快地工作。

所以有人说,创建了一个使用“个人用户帐户”的默认ASP.NET核心项目。现在我想弄清楚该控制器需要什么DI接线来“工作”。

查看帐户控制器构造函数:

public AccountController(UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        IOptions<IdentityCookieOptions> identityCookieOptions,
        IEmailSender emailSender,
        ISmsSender smsSender,
        ILoggerFactory loggerFactory)

除此之外,还会生成以下相关类:

public class ApplicationUser : IdentityUser
{
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    ...
}

和一些相关的DI配置:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...
    app.UseIdentity();
}

在ASP.NET核心标识的源代码中,UserStore强制约束IdentityUser

public class UserStore : UserStore<IdentityUser<string>>

对于我想要工作的是以下内容 - 对于初学者:

public class AuthenticationDbContext : DbContext
{
    public AuthenticationDbContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<ApplicationUser> ApplicationUsers { get; set; }
    public DbSet<ApplicationRole> ApplicationRoles { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<ApplicationUser>(te =>
          te.HasKey(user => user.Id));

        builder.Entity<ApplicationRole>(te =>
          te.HasKey(role => role.Id));
     }
}

public class ApplicationRole
{
    public int Id { get; set; }
    public string UserName { get; set; }
}

public class ApplicationUser
{
    public int Id { get; set; }
    public Guid Guid { get; set; }
    public string GivenName { get; set; }
    public string FamilyName { get; set; }
    public string MiddleName { get; set; }
    public DateTime? DateOfBirth { get; set; }
    public string UserName { get; set; }
    public string EmailAddress { get; set; }
}

如果我列出了我遇到的问题,例外等,这篇文章太长了。

问题是,如何将其与DI配置连接起来?

1 个答案:

答案 0 :(得分:0)

行。保持我的AuthenticationDbContext不变,我可以提供IUserStoreIRoleStore的实现,并按如下方式配置DI。

public class ApplicationUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>
{
    private readonly AuthenticationDbContext _dbContext;

    public ApplicationUserStore(AuthenticationDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    ...

好的,所以我需要提供10或11种方法的实现,这需要一点点搞清楚。对于ApplicationRoleStore也一样。

public class ApplicationRoleStore : IRoleStore<ApplicationRole>
{
    private AuthenticationDbContext _dbContext;

    public ApplicationRoleStore(AuthenticationDbContext context, IdentityErrorDescriber describer = null) 
    {
        _dbContext = context;
    }

    ...

然后可以连接:

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentity<ApplicationUser, ApplicationRole>()
        .AddUserStore<ApplicationUserStore>()
        .AddRoleStore<ApplicationRoleStore>()
        .AddDefaultTokenProviders();

     services.AddTransient(c =>
            new AuthenticationDbContext(
                new DbContextOptionsBuilder()
                    .UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).Options));

因此,当我点击登录时,通过帐户控制器/登录视图登录现在会调用我的ApplicationUserStore.FindByNameAsync

这是否适当&#34;正确&#34;有待观察。我强烈认为ASP.NET身份应该与&#34;任何&#34;数据存储实现,因此您不应该被限制为使用IdentityUser。以上内容适用于我认为的非实体框架实现。