Не вдалося вирішити службу для типу "Microsoft.AspNetCore.Identity.UserManager" під час спроби активувати "AuthController"


95

Я отримую цю помилку в Контролері входу.

InvalidOperationException: Не вдається розпізнати службу для типу "Microsoft.AspNetCore.Identity.UserManager`1 [Automobile.Models.Account]" під час спроби активувати "Automobile.Server.Controllers.AuthController".

ось конструктор Auth Controller:

private SignInManager<Automobile.Models.Account> _signManager;
    private UserManager<Automobile.Models.Account> _userManager;

    public AuthController(UserManager<Models.Account> userManager,
                          SignInManager<Automobile.Models.Account> signManager)
    {
        this._userManager = userManager;
        this._signManager = signManager;
    }

і ось ConfigureServices у startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);
        services.Configure<AppConfig>(Configuration.GetSection("AppSettings"));

        //var provider = HttpContext.ApplicationServices;
        //var someService = provider.GetService(typeof(ISomeService));


        services.AddDbContext<Providers.Database.EFProvider.DataContext>(options => options
            .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                 b => b.MigrationsAssembly("Automobile.Server")
            ));


        services.AddIdentity<IdentityUser, IdentityRole>(options =>
        {
            options.User.RequireUniqueEmail = false;
        })
        .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
        .AddDefaultTokenProviders(); 
        //services.AddScoped<SignInManager<Automobile.Models.Account>, SignInManager<Automobile.Models.Account>>();
        //services.AddScoped<UserManager<Automobile.Models.Account>, UserManager<Automobile.Models.Account>>();

        services.AddMvc();
        App.Service = services.BuildServiceProvider();

        // Adds a default in-memory implementation of IDistributedCache.
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.CookieHttpOnly = true;
        });

    }

22
Мені здається, ви реєструєтесь IdentityUserяк базовий клас користувача, але потім використовуєте Automobile.Models.Account, який, звичайно, ніде не реєструється ASP.NET Identity
Федеріко Діпума,

@FedericoDipuma Велике спасибі :) Вирішено.
OMID

Як ти це вирішив ..?
Рафаель

4
@Lobato в сервісах. AddIdentity просто замінює IdentityUser своїм класом Identity User
OMID

1
@OMID, чому б вам не розмістити свій коментар як відповідь, це мене врятувало, але після серйозного головного болю RnD ..
Null Pointer

Відповіді:


89

Вам потрібно використовувати ту саму модель даних користувачів у SignInManager, UserManager та services.AddIdentity. Той самий принцип відповідає дійсності, якщо ви використовуєте власний клас прикладної рольової програми.

Отже, зміни

services.AddIdentity<IdentityUser, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();

до

services.AddIdentity<Automobile.Models.Account, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();

2
У мене схожа проблема, у мене є користувач і роль клієнта, визначені в методі AddIdentity, і я все ще отримую ту саму помилку. Будь-яка ідея чому? Я міг би розмістити свій код в окремій темі.
devC

1
Насправді я вирішив цю проблему, але зараз зіткнувся з проблемою створення з'єднання з БД. Я опублікую проблему.
devC


здається, ваш рядок підключення встановлений неправильно, перевірте мою відповідь у вашому дописі.
HojjatK,

49

Щоб ясніше відповісти:

Якщо ви використовуєте клас ApplicationUserу startup.cs:services.AddIdentity<ApplicationUser, IdentityRole>()

тоді ви повинні використовувати той самий клас у своєму контролері під час ін'єкції:

public AccountController(UserManager<ApplicationUser> userManager)

Якщо ви використовуєте якийсь інший клас, такий як:

public AccountController(UserManager<IdentityUser> userManager)

тоді ви отримаєте цю помилку:

InvalidOperationException: Не вдається вирішити службу для типу "Microsoft.AspNetCore.Identity.UserManager`1 [IdentityUser]"

оскільки ви використовували ApplicationUserпри запуску, не IdentityUserтакий тип не зареєстрований у системі впорскування.


6
Це враховується для всіх посилань, тому, якщо ви впроваджуєте нову ідентифікацію Razor для asp.net core 2.1 для заміни вашої старої системи ідентифікації, вам потрібно замінити їх автоматичну реалізацію таких речей, як SignInManager <IdentityUser>, на SignInManager <ApplicationUser> скрізь, де вона використовується. Це може дратувати. Також вам потрібно перенаправити маршрут із звичайного / Обліковий запис / Вхід в / Ідентичність / Обліковий запис / Вхід тощо, лише кілька порад, які допоможуть;)
Йохан Герстад,

15

Це трохи не пов’язано з оригінальною публікацією, але оскільки Google призводить вас сюди ... якщо ви отримуєте цю помилку і використовуєте:

services.AddIdentityCore<YourAppUser>()

Потім вам потрібно буде вручну зареєструвати матеріали, які AddIdentityце робить, які можна знайти тут: https://github.com/aspnet/Identity/blob/feedcb5c53444f716ef5121d3add56e11c7b71e5/src/Identity/IdentityServiceCollectionExtensions.cs#L79

        services.AddHttpContextAccessor();
        // Identity services
        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
        services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
        // No interface for the error describer so we can add errors without rev'ing the interface
        services.TryAddScoped<IdentityErrorDescriber>();
        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
        services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
        services.TryAddScoped<UserManager<TUser>>();
        services.TryAddScoped<SignInManager<TUser>>();
        services.TryAddScoped<RoleManager<TRole>>();

Вам потрібно буде замінити TUserі TRoleсвоїми реалізаціями, або типовими IdentityUser,IdentityRole


Довелося створити власний SignInManager, і це виправлено, якщо ви плануєте це зробити, перевірте github.com/dotnet/docs/issues/14828
perustaja

Спочатку я розпочав цей шлях, але знайшов рішення тут ( stackoverflow.com/a/60752194/1146862 ) більш прямим; Єдина зміна, яку мені довелося внести (після повторного замовлення AddIdentityта AddJwtBearerвстановлення всіх трьох параметрів, показаних у прикладі; я тільки використовував DefaultAuthenticationScheme. Я все ще отримую файл cookie при вході, але [Authorize]тепер працює для токенів JWT, не вказуючи Схема автентифікації.
Аарон,

4

не забудьте додати менеджер ролей у ConfigureServices

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>() // <--------
    .AddDefaultUI(UIFramework.Bootstrap4)
    .AddEntityFrameworkStores<ApplicationDbContext>();

3

Ви можете встановити IdentityUser та IdentityRole у ConfigureServices всередині класу автозавантаження окремо, як показано нижче:

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

АБО

Ви можете налаштувати безпосередньо в AddIdentity:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

4
Маючи відповідь лише за кодом, OP та інші навряд чи дізнаються про проблему, подумайте про редагування відповіді та додавання пояснення
Cleptus

0

Якщо ви використовуєте "IdentityServer", тож IdentityServer автентифікує користувача та авторизує клієнта. За замовчуванням IdentityServer насправді не стосується управління користувачами. Але є певна підтримка asp.net Identity

Тому вам потрібно додати:

services.AddIdentityServer()
    .AddAspNetIdentity<ApplicationUser>();

0

Вам потрібно оновити клас Statup.cs нижче

services.AddIdentity <ApplicationUser, IdentityRole> () .AddEntityFrameworkStores ();

Тут: ApplicationUser - це мій власний клас моделі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.