Blazor项目扩展AspNetUsers表字段时触发多个Identity报错
报错根因
你遇到的所有报错核心原因是扩展ASP.NET Core Identity用户字段时操作逻辑不符合框架约定:
- 直接给默认
IdentityUser类加字段的方式不被EF Core支持,必须通过自定义派生用户类实现字段扩展 - 你的
ApplicationDbContext继承的是非泛型版本IdentityDbContext,没有绑定自定义用户类型,导致Identity关联表(如IdentityUserLogin)的主键配置缺失 - 服务注册、控制器注入的
UserManager/SignInManager全用了默认IdentityUser类型,和上下文模型不匹配 - 之前生成的不完整迁移文件、残留缓存会触发资源类型物化失败的鉴别器报错
正确实现步骤
第一步:创建自定义用户实体
在项目Entities目录下新建ApplicationUser类,继承默认IdentityUser,新增需要的3个字段:
using Microsoft.AspNetCore.Identity; namespace LoginAndAuthProj.Server.Entities { public class ApplicationUser : IdentityUser { public string UsersAddress { get; set; } public int CityID { get; set; } public byte[] PictureOfUser { get; set; } } }
第二步:修改DbContext绑定自定义用户类型
将原来的非泛型IdentityDbContext替换为泛型版本,绑定自定义用户类,注意OnModelCreating中必须先调用基类方法完成Identity默认表配置,再写自定义逻辑:
using LoginAndAuthProj.Server.Entities; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.InMemory.ValueGeneration.Internal; using System; namespace LoginAndAuthProj.Server.MainDbContext { // 泛型参数依次为:自定义用户类、角色类、用户主键类型(默认string) public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole, string> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 必须优先调用基类配置,否则Identity内置表的主键、索引配置不会生效 base.OnModelCreating(modelBuilder); modelBuilder.Entity<MyEventUserLog>(entity => { var pb = entity.Property(e => e.UId).ValueGeneratedOnAdd(); if (Database.IsInMemory()) { pb.HasValueGenerator<InMemoryIntegerValueGenerator<decimal>>(); } }); // 可选:给新增字段配置数据库映射规则 modelBuilder.Entity<ApplicationUser>(entity => { entity.Property(e => e.UsersAddress).HasMaxLength(256); entity.Property(e => e.PictureOfUser).HasColumnType("varbinary(max)"); }); } public DbSet<MyEventUserLog> MyEventUserLogs { get; set; } } }
第三步:修改Startup的Identity服务注册
将注册Identity时使用的默认IdentityUser替换为自定义的ApplicationUser:
// 替换原来的 services.AddIdentity<IdentityUser, IdentityRole>() services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders();
第四步:修改AccountController的依赖注入和用户逻辑
将控制器中所有用到IdentityUser的地方替换为ApplicationUser:
- 调整注入的Manager泛型参数:
private readonly UserManager<ApplicationUser> _userManager; private readonly SignInManager<ApplicationUser> _signInManager; private readonly IConfiguration _configuration; public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, IConfiguration configuration) { _userManager = userManager; _signInManager = signInManager; _configuration = configuration; } - 调整创建用户的实例化逻辑,给新增字段赋初始值:
[HttpPost("Create")] public async Task<ActionResult<UserToken>> CreateUser([FromBody] UserInfo model) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email, PhoneNumber = "00000011110000", EmailConfirmed = true, PhoneNumberConfirmed = true, TwoFactorEnabled = false, LockoutEnabled = false, AccessFailedCount = 0, // 新增字段初始值,后续可根据业务从请求参数传值 UsersAddress = string.Empty, CityID = 0, PictureOfUser = Array.Empty<byte>() }; try { var result = await _userManager.CreateAsync(user, model.StrPassword); if (result.Succeeded) { return BuildToken(model); } else { return BadRequest("用户名或密码格式不符合要求"); } } catch (Exception ex) { return BadRequest(ex.Message); } }
其余查询、登录逻辑不需要修改,_userManager的返回值会自动映射为ApplicationUser类型。
第五步:清理旧迁移同步数据库结构
- 删除项目Migrations文件夹下所有历史迁移文件
- 打开包管理器控制台依次执行命令生成新迁移、更新数据库:
Add-Migration AddCustomUserFields Update-Database
执行完成后AspNetUsers表就会自动新增你需要的3个字段。
残留报错排查
- 如果还提示discriminator鉴别器相关错误,删除数据库中
__EFMigrationsHistory表的所有记录,重新执行迁移即可,该错误是历史不完整迁移导致的配置缺失 - 如果提示类型不匹配,清理项目bin、obj文件夹后重新生成解决方案
- 不要直接手动修改数据库表加字段,必须通过EF Core迁移同步结构,否则会出现模型与数据库结构不匹配的问题
内容的提问来源于stack exchange,提问作者pufivina
相关产品推荐
相关产品推荐

