【发布时间】:2020-09-20 09:45:46
【问题描述】:
情况
我正在使用带有 Angular 8 模板的 Identity ASP.NET Core 3.1。我想扩展 ASPNETUserRoles 表并在其中添加另一个自定义键列 CompanyId。
默认身份提供:
public virtual TKey UserId { get; set; }
public virtual TKey RoleId { get; set; }
当我将我的 DbContext 从 UserId (string) 修改为 UserId (long) 时,DbContext 看起来像:
public class CompanyDBContext : KeyApiAuthorizationDbContext<User, Role, UserRole, long>
{
public CompanyDBContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
public DbSet<Company> Companies { get; set; }
}
KeyApiAuthorizationDbContext
public class KeyApiAuthorizationDbContext<TUser, TRole, IdentityUserRole, TKey> : IdentityDbContext<TUser, TRole, TKey, IdentityUserClaim<TKey>, IdentityUserRole<TKey>, IdentityUserLogin<TKey>, IdentityRoleClaim<TKey>, IdentityUserToken<TKey>>, IPersistedGrantDbContext
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where IdentityUserRole : IdentityUserRole<TKey>
where TKey : IEquatable<TKey>
{
private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;
/// <summary>
/// Initializes a new instance of <see cref="ApiAuthorizationDbContext{TUser, TRole, TKey}"/>.
/// </summary>
/// <param name="options">The <see cref="DbContextOptions"/>.</param>
/// <param name="operationalStoreOptions">The <see cref="IOptions{OperationalStoreOptions}"/>.</param>
public KeyApiAuthorizationDbContext(
DbContextOptions options,
IOptions<OperationalStoreOptions> operationalStoreOptions)
: base(options)
{
_operationalStoreOptions = operationalStoreOptions;
}
/// <summary>
/// Gets or sets the <see cref="DbSet{PersistedGrant}"/>.
/// </summary>
public DbSet<PersistedGrant> PersistedGrants { get; set; }
/// <summary>
/// Gets or sets the <see cref="DbSet{DeviceFlowCodes}"/>.
/// </summary>
public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }
Task<int> IPersistedGrantDbContext.SaveChangesAsync() => base.SaveChangesAsync();
/// <inheritdoc />
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value);
}
}
实体
public class User : IdentityUser<long> {}
public class Role : IdentityRole<long> {}
public class UserRole : IdentityUserRole<long>
{
public long CompanyId { get; set; }
}
出现问题
当我注册我的用户并返回 true 时,我将在 UserRole 表中添加一个当前用户,如下所示,但是当我的调试器到达 await _context.SaveChangesAsync(); 方法时,它向我显示了一个异常
if (result.Succeeded)
{
foreach (var role in model.Roles.Where(x => x.IsChecked = true))
{
var entity = new Core.Entities.Identity.UserRole()
{
UserId = model.User.Id,
RoleId = role.Id,
CompanyId = companycode
};
_context.UserRoles.Add(entity);
}
await _context.SaveChangesAsync();
}
我不知道我在哪里犯错?如果上述覆盖用户角色的步骤是错误的,那么请协助我。
我还分享了我的迁移详细信息以供您参考,这可能是我做错了。
迁移
migrationBuilder.CreateTable(
name: "Companies",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(nullable: false),
Code = table.Column<string>(nullable: false),
Logo = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Companies", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<long>(nullable: false),
RoleId = table.Column<long>(nullable: false),
CompanyId = table.Column<long>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId, x.CompanyId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_Companies_CompanyId",
column: x => x.CompanyId,
principalTable: "Companies",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
迁移快照
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<long>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("ClaimType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(max)");
b.Property<long>("RoleId")
.HasColumnType("bigint");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
【问题讨论】:
-
为什么不在用户上添加公司?你的用例是什么需要公司 ID 作为角色
-
@EduCielo 因为我在企业级管理用户,因此我想为此使用 aspnetuserroles。我不想再创建一个同时管理 UserId 和 CompanyId 的表。
-
在我的情况下我没有收到此错误“无效的列鉴别器”
-
docs.microsoft.com/en-us/aspnet/core/security/authentication/… 这包括正确的配置。我没有看到您在模型构建器上将关系配置到公司实体中
标签: asp.net-mvc entity-framework asp.net-core entity-framework-core asp.net-core-identity