Объект ModelBuilder в ASP.NET Core MVC

В ASP.NET Core 6 мне нужно переименовать модель базы данных ASP.NET Core Identity. Я не использую API, а просто ASP.NET Core 6 MVC.

Это мой код:

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

    modelBuilder.Entity<AppUser>().ToTable("Users");
    modelBuilder.Entity<AppUser>().Property(up => up.Id).HasColumnName("UserId");

    modelBuilder.Entity<IdentityRole>().ToTable("Roles");
    modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRoles", "dbo");
    modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaims", "dbo");
    modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogins", "dbo");
}

Код файла программы:

builder.Services.AddDefaultIdentity<AppUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddEntityFrameworkStores<ApplicationDbContext>();

AppUser класс:

public partial class User : IdentityUser

Но я получаю сообщение об ошибке в этой строке кода в файле Program:

var app = builder.Build();

Вот подробности ошибки:

System.AggregateException
HResult=0x80131500
Сообщение = Невозможно создать некоторые службы (ошибка при проверке дескриптора службы «ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory1 [Microsoft.AspNetCore.Identity.IdentityUser]»: невозможно разрешить службу для типа «School.Web»). .Data.ApplicationDbContext» при попытке активировать «Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore6[Microsoft.AspNetCore.Identity.IdentityUser,School.Web.Data.ApplicationDbContext,System.String,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System.String],Microsoft.AspNetCore.Identity.IdentityUserLogin1[System.String],Microsoft.AspNetCore.Identity.IdentityUserToken1[System.String]]».) (Ошибка при проверке дескриптор службы «ServiceType: Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]»: невозможно разрешить службу для типа «School.Web.Data.ApplicationDbContext» при попытке активировать «Microsoft.AspNetCore.Identity» .EntityFrameworkCore.UserOnlyStore6[Microsoft.AspNetCore.Identity.IdentityUser,School.Web.Data.ApplicationDbContext,System.String,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System.String],Microsoft.AspNetCore.Identity.IdentityUserLogin1[System.String],Microsoft.AspNetCore.Identity.IdentityUserToken1[System.String]]'.) (Ошибка при проверке дескриптора службы 'ServiceType: Microsoft.AspNetCore.Identity.ISecurityStampValidator Lifetime: Scoped) Тип реализации: Microsoft.AspNetCore.Identity.SecurityStampValidator1[Microsoft.AspNetCore.Identity.IdentityUser]': Unable to resolve service for type 'School.Web.Data.ApplicationDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore6[Microsoft.AspNetCore.Identity.IdentityUser,School.Web.Data.ApplicationDbContext,System.String,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System.String],Microsoft.AspNetCore.Identity.IdentityUserLogin1[System.String],Microsoft.AspNetCore .Identity.IdentityUserToken1[System.String]]'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.ITwoFactorSecurityStampValidator Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.TwoFactorSecurityStampValidator1[Microsoft.AspNetCore.Identity.IdentityUser]': невозможно разрешить службу для типа 'School.Web.Data.ApplicationDbContext' при попытке активировать 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore6[Microsoft.AspNetCore.Identity.IdentityUser,School.Web.Data.ApplicationDbContext,System.String,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System .String],Microsoft.AspNetCore.Identity.IdentityUserLogin1[System.String],Microsoft.AspNetCore.Identity.IdentityUserToken1[System.String]]'.) (Ошибка при проверке дескриптора службы 'ServiceType: Microsoft.AspNetCore.Identity.SignInManager`1[Microsoft.AspNetCore.Identity.IdentityUser]

Внутреннее исключение 1: InvalidOperationException: ошибка при проверке дескриптора службы «ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory1 [Microsoft.AspNetCore.Identity.IdentityUser]»: невозможно разрешить службу для типа «School.Web.Data.ApplicationDbContext». при попытке активировать «Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore6[Microsoft.AspNetCore.Identity.IdentityUser,School.Web.Data.ApplicationDbContext,System.String,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System.String],Microsoft.AspNetCore.Identity.IdentityUserLogin1[System.String],Microsoft.AspNetCore.Identity.IdentityUserToken1[System.String]]».

Внутреннее исключение 2: InvalidOperationException: невозможно разрешить службу для типа «School.Web.Data.ApplicationDbContext» при попытке активировать «Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserOnlyStore6[Microsoft.AspNetCore.Identity.IdentityUser,School.Web.Data.ApplicationDbContext,System.String,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System.String],Microsoft.AspNetCore.Identity.IdentityUserLogin 1[System.String],Microsoft.AspNetCore.Identity.IdentityUserToken1[System.String]]'.

Можете ли вы подтвердить, что правильное наследование для вас dbContext — ApplicationDbContext : IdentityDbContext<AppUser> и что вы правильно зарегистрировали свой dbContext в Program.cs?

mrSoh 12.07.2024 17:15

Да, я обновил свой пост, теперь вы можете его увидеть.

MrMustafa022 12.07.2024 17:28

Но класс AppUser находится на другом слое модели.

MrMustafa022 12.07.2024 17:29

Убедитесь, что независимо от того, используете ли вы program.cs непосредственно для конфигураций или отдельный класс расширений, вы зарегистрировали свой dbContext и добавили идентификатор следующим образом: var ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection‌​"); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddDefaultIdentity<AppUser>(options => options.SignIn.RequireConfirmedAccount = true).AddRoles<IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>();

mrSoh 12.07.2024 17:45

Да, ApplicationDbContext находится в отдельном классе расширений на другом уровне.

MrMustafa022 12.07.2024 17:52

Если у вас есть собственный AppUser, вам также нужно будет сделать то же самое для всех связанных классов, таких как IdentityUserRole. Кроме того, вам нужно будет использовать IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> для вашего контекста, а также применить изменения к UserManager и SignInManager.

iSR5 12.07.2024 19:21

@ iSR5, Да, я внес все необходимые изменения, но получаю ту же ошибку. Можете ли вы мне помочь - это нелегко сделать - я чувствую, что здесь потерялся - не могли бы вы дать мне полный код в качестве решения?

MrMustafa022 14.07.2024 14:13

@MrMustafa022, какую сетевую версию вы используете?

iSR5 14.07.2024 20:46

Версия ASP.NET Core 6.

MrMustafa022 14.07.2024 21:55

Привет @MrMustafa022, возникает ли исключение при запуске приложения? Я не могу воспроизвести проблему при тестировании вашего текущего кода. Возможно, вам лучше поделиться минимальным репозиторием, который может воспроизвести проблему.

Rena 15.07.2024 10:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша главная проблема в том, что вы не прописали на таможне необходимые услуги AppUser. Вам необходимо зарегистрировать UserManager, RoleManager и UserClaimsPrincipalFactory как сервисы Scoped с новой моделью AppUser. Не уверен, что я что-то упустил, но чтобы иметь полный контроль над моделями удостоверений, вам придется реализовать собственную модель для каждой модели удостоверения и наследовать ее исходную модель. Кроме того, вам придется реализовать пользовательские UserManager и RoleManager, а также UserClaimsPrincipalFactory.

Вот как переопределить идентификатор по умолчанию (.NET 6+) (здесь я использую int как TKey вместо string, вы можете использовать string, если хотите):

Модели идентичности

public sealed class ApplicationIdentityRole : IdentityRole<int> { }

public sealed class ApplicationIdentityRoleClaim : IdentityRoleClaim<int> { }

public sealed class ApplicationIdentityUser : IdentityUser<int> { }

public sealed class ApplicationIdentityUserClaim : IdentityUserClaim<int> { }

public sealed class ApplicationIdentityUserLogin : IdentityUserLogin<int> { }

public sealed class ApplicationIdentityUserRole : IdentityUserRole<int> { }

public sealed class ApplicationIdentityUserToken : IdentityUserToken<int> { }

Менеджеры идентификации

public sealed class ApplicationUserManager : UserManager<ApplicationIdentityUser>
{
    public ApplicationUserManager(IUserStore<ApplicationIdentityUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationIdentityUser> passwordHasher, IEnumerable<IUserValidator<ApplicationIdentityUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationIdentityUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationIdentityUser>> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
    {
    }
}

public sealed class ApplicationRoleManager : RoleManager<ApplicationIdentityRole>
{
    public ApplicationRoleManager(IRoleStore<ApplicationIdentityRole> store, IEnumerable<IRoleValidator<ApplicationIdentityRole>> roleValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, ILogger<RoleManager<ApplicationIdentityRole>> logger) : base(store, roleValidators, keyNormalizer, errors, logger)
    {
    }
}


public sealed class ApplicationUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationIdentityUser, ApplicationIdentityRole>
{
    public ApplicationUserClaimsPrincipalFactory(UserManager<ApplicationIdentityUser> userManager, RoleManager<ApplicationIdentityRole> roleManager, IOptions<IdentityOptions> options) : base(userManager, roleManager, options)
    {
    }
}

ИдентитиДбКонтекст

public sealed class ApplicationDbContext : IdentityDbContext<ApplicationIdentityUser, ApplicationIdentityRole, int, ApplicationIdentityUserClaim, ApplicationIdentityUserRole, ApplicationIdentityUserLogin, ApplicationIdentityRoleClaim, ApplicationIdentityUserToken>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
    {
    }

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

        modelBuilder.Entity<ApplicationIdentityUser>().ToTable("IdentityUsers");
        modelBuilder.Entity<ApplicationIdentityRole>().ToTable("IdentityRoles");
        modelBuilder.Entity<ApplicationIdentityRoleClaim>().ToTable("IdentityRoleClaims");
        modelBuilder.Entity<ApplicationIdentityUserRole>().ToTable("IdentityUserRoles");
        modelBuilder.Entity<ApplicationIdentityUserClaim>().ToTable("IdentityUserClaims");
        modelBuilder.Entity<ApplicationIdentityUserLogin>().ToTable("IdentityUserLogins");
        modelBuilder.Entity<ApplicationIdentityUserToken>().ToTable("IdentityUserTokens");

    }
}

DI-услуги

builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
   
builder.Services.AddIdentity<ApplicationIdentityUser, ApplicationIdentityRole>(options => 
{ 
    // set Identity options here
})
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddUserManager<ApplicationUserManager>()
    .AddRoleManager<ApplicationRoleManager>()                
    .AddClaimsPrincipalFactory<ApplicationUserClaimsPrincipalFactory>()  
    .AddDefaultTokenProviders();

Вы можете изучить остальные параметры, которые уже предоставлены в коллекции сервисов (например, AddSignInManager), чтобы иметь представление о настраиваемых параметрах.

Привет, iSR5, но я получаю эту ошибку: связь между «RoleClaim» и «Role» со свойствами внешнего ключа {'RoleId': int} не может быть нацелена на первичный ключ {'Id': string}, поскольку он несовместим.

MrMustafa022 17.07.2024 19:53

RoleId — это строка в RoleClaim, а идентификатор в Role также является строкой.

MrMustafa022 17.07.2024 19:54

@MrMustafa022 измените int на string для всех моделей идентичности в приведенных выше примерах. Это должно решить проблему.

iSR5 17.07.2024 20:29

Да, все работает правильно, но я получаю сообщение об ошибке: SqlException: неверное имя столбца «UserId1». Недопустимое имя столбца «UserId1».

MrMustafa022 19.07.2024 15:01

Я использую этот код, чтобы изменить идентификатор на UserId: modelBuilder.Entity<User>().Property(up => up.Id).HasColumnName("UserId");

MrMustafa022 19.07.2024 15:01

@MrMustafa022 MrMustafa022 Я не рекомендую менять имя первичного ключа; потому что все с этим связано. Кроме того, UserId — это имя внешнего ключа. в качестве соглашения об именовании внешнего ключа будет использоваться имя таблицы в качестве префикса и имя столбца в качестве суффикса (например, UserId). А Id — это наиболее используемый и известный первичный ключ для любой таблицы в любой базе данных.

iSR5 19.07.2024 18:14

@MrMustafa022, если этого невозможно избежать, вам нужно будет изменить FK для каждой связанной таблицы, такой как UserRole, UserClaims, UserLogins и так далее.

iSR5 19.07.2024 18:17

Нет проблем, я меняю его на Id, и все работает правильно, но я получаю ошибку: UserManager имеет значение Null.

MrMustafa022 19.07.2024 19:01

Код: общественный ApplicationUserManager UserManager {get {return _userManager; } Частный набор { _userManager = значение; } }

MrMustafa022 19.07.2024 19:03

общедоступный запечатанный класс ApplicationUserManager : UserManager<User> { public ApplicationUserManager(IUserStore<User> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<User> парольHasher, IEnumerable<IUserValidator<User>> userValidators, IEnumerable<IPasswordValidator<User>>passwordValidators, Нормализатор keyNormalizer, ошибки IdentityErrorDescriber, службы IServiceProvider, регистратор ILogger<UserManager<User>>): base(store, optionsAccessor, парольHasher, userValidators, парольValidators, keyNormalizer, ошибки, службы, регистратор) { } }

MrMustafa022 19.07.2024 19:04

публичный частичный класс User: IdentityUser<string>

MrMustafa022 19.07.2024 19:04

builder.Services.AddIdentity<Пользователь, Роль>(параметры =>

MrMustafa022 19.07.2024 19:08

Давайте продолжим обсуждение в чате.

iSR5 19.07.2024 19:11

Другие вопросы по теме