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


94

我在登录控制器中收到此错误。

InvalidOperationException:尝试激活“ Automobile.Server.Controllers.AuthController”时,无法解析类型为“ Microsoft.AspNetCore.Identity.UserManager`1 [Automobile.Models.Account]”的服务。

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

这是startup.cs中的ConfigureServices:

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

    }

20
在我看来,您正在注册IdentityUser为基本用户类,但随后使用Automobile.Models.Account,那当然不是ASP.NET Identity在任何地方注册的
Federico Dipuma

@FedericoDipuma非常感谢:)解决了。
OMID

您是如何解决的..?
拉斐尔

4
services.AddIdentity中的@Lobato只需将IdentityUser替换为您的Identity User类
OMID

1
@OMID你为什么不张贴作为回答您的意见,这救了我,但之后RND的一些严重的头痛..
空指针

Answers:


89

您需要在SignInManager,UserManager和services.AddIdentity中使用相同的用户数据模型。如果您使用自己的定制应用程序角色模型类,则相同的主体为true。

所以,改变

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
这对所有引用都是重要的,因此,如果您为asp.net core 2.1实现新的Razor身份以替换旧的Identitysystem,则无论在何处使用,都需要将它们的诸如SignInManager <IdentityUser>之类的自动实现替换为SignInManager <ApplicationUser>。这可能很烦人。另外,您需要从正常的/ Account / Login重新路由到/ Identity / Account / Login等。仅提供一些帮助的技巧;)
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>>();

您需要将替换为TUserTRole并替换为这些实现或默认的IdentityUserIdentityRole


必须创建一个自定义的SignInManager并对其进行修复,如果您打算这样做,请检查github.com/dotnet/docs/issues/14828
perustaja

我最初是从这条路线开始的,但是发现这里的解决方案(stackoverflow.com/a/60752194/1146862)更简单;我唯一要做的更改(重新排序后AddIdentityAddJwtBearer是要设置示例中显示的所有三个选项;我只是一直使用DefaultAuthenticationScheme。我仍然可以在登录时重新获得cookie,但是[Authorize]现在可以在JWT令牌中使用而无需指定AuthenticationSchema。
阿伦

4

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

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

3

您可以在Startup类内的ConfigureServices中分别设置IdentityUser和IdentityRole,如下所示:

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是我的自定义模型类。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.