更改默认 ASP.NET IdentityUser 表的表名称不起作用

问题描述 投票:0回答:1

我正在将 .Net Framework 4.7.2 mvc 网站升级到 ASP.NET Core (.Net8)。旧站点使用EntityFramework 6.4和Microsoft.AspNet.Identity.Core 2.2。新站点使用 EntityFrameworkCore 8.0 和 Microsoft.AspNetCore.Identity.EntityFramework 8.0。

现有数据库包含早期身份框架中的表。表名和列几乎相同:

IdentityRole, IdentityUser, IdentityUserClaim, IdentityUserLogin, IdentityUserRole
。但是,
IdentityUser
不包含新的
ConcurrencyStamp
字段,同时还包含自定义字段
LastLoginTime

我对数据库进行了逆向工程以创建新的实体框架模型,并且我认为我已经正确确定我应该使用生成的

Identity...
类,因为这些似乎是由身份框架提供的(对吗?)

因此剩下两个需求:

  1. 自定义 IdentityUser 以包含自定义
    LastLoginTime
    字段
  2. 确保默认身份类映射到现有表名称。

阅读诸如(使用 ASP.NET Identity 时如何更改表名称?)之类的答案表明我应该能够简单地从

.ToTable("IdentityUser")
调用
OnModelCreating(ModelBuilder modelBuilder)

ApplicationDbContext.cs

public partial class ApplicationDbContext : IdentityDbContext<IdentityUser> {
    public ApplicationDbContext(DbContextOptions options) : base(options) {}

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    
        modelBuilder.Entity<ApplicationUser>(entity =>
        {
            entity.ToTable("IdentityUser");
            entity.Property(e => e.LastLoginTime).HasColumnType("datetime");
            entity.Property(e => e.LockoutEnd).HasColumnName("LockoutEndDateUtc").HasColumnType("datetime)");
        });
    }

ApplicationUser.cs

public class ApplicationUser : IdentityUser
{
    public DateTime? LastLoginTime { get; set; }

    public ApplicationUser()
        : base() { }
    public ApplicationUser(string userName)
        : base(userName) {}
}

HomeController.cs

    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly SignInManager<ApplicationUser> _signInManager;
        private readonly UserManager<ApplicationUser> _userManager;

        public HomeController(ILogger<HomeController> logger, SignInManager<ApplicationUser> signInManager, UserManager<ApplicationUser> userManager)
        {
            _logger = logger;
            _signInManager = signInManager;
            _userManager = userManager;
        }

        public async Task<ActionResult> Login(LoginViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            var identityUser = await _signInManager.UserManager.FindByNameAsync(model.UserName);
            // EXCEPTION
        }
    }

程序.cs

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
        builder.Services.AddMvcCore().AddJsonOptions(o =>
        {
            o.JsonSerializerOptions.PropertyNamingPolicy = null;
            o.JsonSerializerOptions.DictionaryKeyPolicy = null;
        });

        builder.Services.AddDistributedMemoryCache();

        builder.Services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromMinutes(5);
            options.Cookie.HttpOnly = true;
            options.Cookie.IsEssential = true;
        });

        builder.Services.AddDbContext<ApplicationDbContext>(options =>
            options.UseMySQL(builder.Configuration.GetConnectionString("Default") ?? ""));

        builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            options.Password.RequiredLength = 8;
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
            options.Lockout.MaxFailedAccessAttempts = 5;
        })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        builder.Services.AddHttpContextAccessor();

        var app = builder.Build();

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();
        app.UseSession();

        app.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");

        AppDomain.CurrentDomain.SetData("ContentRootPath", builder.Environment.ContentRootPath);
        AppDomain.CurrentDomain.SetData("WebRootPath", builder.Environment.WebRootPath);

        app.Run();
    }

当我测试我的控制器时,我看到:

MySql.Data.MySqlClient.MySqlException (0x80004005): Table 'MyDb.AspNetUsers' doesn't exist
  [...omitted]
 at Microsoft.AspNetCore.Identity.UserManager`1.FindByNameAsync(String userName)

为什么

FindByNameAsync
搜索
AspNetUsers
而不是我通过
ToTable("IdentityUser")
指定的表?

c# asp.net-core-mvc asp.net-identity
1个回答
0
投票

您的

ApplicationDbContext
应源自
ApplicationUser
;不是
IdentityUser

ApplicationDbContext : IdentityDbContext<IdentityUser>

应该是

ApplicationDbContext : IdentityDbContext<ApplicationUser>
© www.soinside.com 2019 - 2024. All rights reserved.