ไม่สามารถแก้ไขบริการสำหรับประเภท '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;
        });

    }

21
สำหรับฉันแล้วดูเหมือนว่าคุณกำลังลงทะเบียนIdentityUserเป็นคลาสผู้ใช้ขั้นพื้นฐาน แต่คุณกำลังใช้Automobile.Models.Accountงานซึ่งแน่นอนว่า ASP.NET Identity ไม่ได้ลงทะเบียนที่ใดก็ได้
Federico Dipuma

@FedericoDipuma ขอบคุณมาก :) แก้ไขแล้ว
OMID

แก้ไขอย่างไร .. ?
Rafael

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
อันที่จริงฉันแก้ไขปัญหานั้นแล้ว แต่ตอนนี้ประสบปัญหาในการสร้างการเชื่อมต่อ DB ฉันจะโพสต์ปัญหา
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 identity ใหม่สำหรับ asp.net core 2.1 เพื่อแทนที่ระบบข้อมูลประจำตัวเก่าของคุณคุณจะต้องแทนที่การใช้งานอัตโนมัติของพวกเขาเช่น SignInManager <IdentityUser> เป็น SignInManager <ApplicationUser> ทุกที่ที่ใช้ อาจเป็นเรื่องที่น่ารำคาญ นอกจากนี้คุณต้องเปลี่ยนเส้นทางจากปกติ / บัญชี / เข้าสู่ระบบไปยัง / ข้อมูลประจำตัว / บัญชี / เข้าสู่ระบบ ฯลฯ เพียงแค่เคล็ดลับบางประการเท่านั้นที่จะช่วยได้)
Johan Herstad

14

นี่ไม่เกี่ยวข้องกับโพสต์ต้นฉบับเล็กน้อย แต่เนื่องจาก 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ฉันยังคงได้รับคุกกี้กลับมาเมื่อเข้าสู่ระบบ แต่[Authorize]ตอนนี้ใช้งานได้กับโทเค็น JWT โดยไม่ต้องระบุ AuthenticationSchema.
Aaron

4

อย่าลืมเพิ่มตัวจัดการบทบาทใน ConfigureServices

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

3

คุณสามารถตั้งค่า IdentityUser และ IdentityRole ใน ConfigureServices ภายในคลาส Startup ทีละรายการดังที่แสดงด้านล่าง:

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 คือคลาสโมเดลที่กำหนดเองของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.