ASP NET核心身份與實體框架自定義DbContext

asp.net-core asp.net-core-identity entity-framework-core

我已經嘗試閱讀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 Core Identity的源代碼中,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配置連接起來?

熱門答案

好。繼續保持我的AuthenticationDbContext相同之後,我可以提供IUserStoreIRoleStore的實現IUserStore如下方式配置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));

因此,當我單擊Login時,通過Account Controller / Login視圖登錄現在會調用我的ApplicationUserStore.FindByNameAsync

這是否“適當”還有待觀察。我強烈認為ASP.NET身份應該與“任何”數據存儲實現一起使用,因此您不必被限制為使用IdentityUser 。以上內容適用於我認為的非實體框架實現。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow