尝试激活“AuthController”时无法解析类型“Microsoft.AspNetCore.Identity.UserManager”的服务

91zkwejq  于 2022-12-15  发布在  .NET
关注(0)|答案(8)|浏览(199)

我在登录控制器中遇到此错误。
无效操作异常:尝试激活“汽车.服务器.控制器.验证控制器”时,无法解析类型“Microsoft.AspNetCore.Identity.UserManager”1[汽车.型号.帐户]“的服务。
下面是身份验证控制器构造函数:

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;
    }

这里是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;
        });

    }
3wabscal

3wabscal1#

您需要在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();
r8xiu3jd

r8xiu3jd2#

先把答案说清楚:
如果在startup.cs中使用类ApplicationUserservices.AddIdentity<ApplicationUser, IdentityRole>()
那么你必须在控制器中使用相同的类来注入它:

public AccountController(UserManager<ApplicationUser> userManager)

如果您使用一些其他类,例如:

public AccountController(UserManager<IdentityUser> userManager)

则会出现以下错误:
无效操作异常:无法解析类型“Microsoft.AspNetCore.Identity.UserManager”1[身份用户]“的服务
因为您在启动时使用了ApplicationUser,而不是IdentityUser,所以此类型未在进样系统中注册。

polkgigr

polkgigr3#

这是一个有点无关的原始职位,但由于谷歌把你带到这里...如果你得到这个错误,并使用:

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>>();

您需要将TUserTRole替换为它们的实现,或者替换为默认的IdentityUserIdentityRole

sxpgvts3

sxpgvts34#

您可以在启动类中的ConfigureServices中单独设置IdentityUser和IdentityRole,如下所示:

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


您可以直接在AddIdentity中配置:

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

mbjcgjjk5#

不要忘记在ConfigureServices中添加角色管理器

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

mnemlml86#

如果您使用的是“IdentityServer”,那么IdentityServer将对用户进行身份验证并对客户端进行授权。默认情况下,IdentityServer实际上与用户管理无关。但它对asp.net Identity提供了一些支持
因此,您需要添加:

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

yc0p9oo07#

您需要使用以下内容更新Statup.cs类
服务。添加身份〈应用程序用户,身份角色〉()。添加实体框架存储();
这里:ApplicationUser是我的自定义模型类。

l2osamch

l2osamch8#

这是一个有点不相关的原始职位作为上面的答案,但由于谷歌把你带到这里...这是一个更简单的解决方案,如果你得到这个错误,并使用:
服务。添加身份核心()
有一个比上面列出的答案更简单的解决方案,比如这个。
假设您有一个名为ApplicationUser的自定义IdentityUser和一个名为ApplicationRole的自定义角色,您可以简单地使用以下内容来工作。

builder
    .Services
    .AddIdentityCore<ApplicationUser>(identityOptions =>
                                      {
                                          identityOptions.Lockout = new LockoutOptions
                                          {
                                              DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30)
                                              , MaxFailedAccessAttempts = 20
                                          };

                                          identityOptions.Password = new PasswordOptions
                                          {
                                              RequireDigit = true
                                              , RequireLowercase = true
                                              , RequireNonAlphanumeric = true
                                              , RequireUppercase = true
                                              , RequiredLength = 8
                                          };

                                          identityOptions.SignIn = new SignInOptions
                                          {
                                              RequireConfirmedAccount = true
                                              , RequireConfirmedEmail = true
                                          };

                                          identityOptions.User = new UserOptions
                                          {
                                              AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.@1234567890!#$%&'*+-/=?^_`{|}~"
                                              , RequireUniqueEmail = true
                                          };
                                      })
    .AddRoles<ApplicationRole>()
    .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<ApplicationUser, ApplicationRole>>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

这就简单多了。
此外,从Microsoft文档中可以看出,您必须像这样声明您的DbContext,它才能进行推断。

public class ApplicationDbContext
    : IdentityDbContext<ApplicationUser
        , ApplicationRole
        , long
        , ApplicationUserClaim
        , ApplicationUserRole
        , ApplicationUserLogin
        , ApplicationRoleClaim
        , ApplicationUserToken>
{
}

当然不一定要使用自定义类型,我在这里使用,可以使用默认值等。

相关问题