Impossible de résoudre le service pour le type «Microsoft.AspNetCore.Identity.UserManager» lors de la tentative d'activation de «AuthController»

95

J'obtiens cette erreur dans le contrôleur de connexion.

InvalidOperationException: impossible de résoudre le service pour le type «Microsoft.AspNetCore.Identity.UserManager» 1 [Automobile.Models.Account] »lors de la tentative d'activation de« Automobile.Server.Controllers.AuthController ».

voici le constructeur 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;
    }

et voici ConfigureServices dans 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;
        });

    }
OMID
la source
21
Il me semble que vous vous enregistrez en IdentityUsertant que classe d'utilisateurs de base, mais que vous utilisez Automobile.Models.Accountce qui, bien sûr, n'est enregistré nulle part par ASP.NET Identity
Federico Dipuma
@FedericoDipuma Merci beaucoup :) Résolu.
OMID
Comment l'avez-vous résolu ..?
Rafael
4
@Lobato in services.AddIdentity remplace simplement IdentityUser par votre classe Identity User
OMID
1
@OMID pourquoi ne postez-vous pas votre commentaire comme réponse, cela m'a sauvé mais après de sérieux maux de tête de RnD ..
Null Pointer

Réponses:

89

Vous devez utiliser le même modèle de données utilisateur dans SignInManager, UserManager et services.AddIdentity. Le même principe est vrai si vous utilisez votre propre classe de modèle de rôle d'application personnalisée.

Alors, changez

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();
HojjatK
la source
2
J'ai le même problème, mon utilisateur client et mon rôle sont définis dans la méthode AddIdentity et j'obtiens toujours la même erreur. Une idée pourquoi? Je pourrais publier mon code dans un fil de discussion séparé.
devC
1
En fait, j'ai résolu ce problème, mais je suis maintenant confronté à un problème de création de la connexion DB. Je posterai le problème.
devC
semble que votre chaîne de connexion n'a pas été définie correctement, consultez ma réponse dans votre message.
HojjatK
49

Juste pour être clair sur la réponse:

Si vous utilisez la classe ApplicationUserdans startup.cs:services.AddIdentity<ApplicationUser, IdentityRole>()

alors vous devez utiliser la même classe dans votre contrôleur lors de son injection:

public AccountController(UserManager<ApplicationUser> userManager)

Si vous utilisez une autre classe telle que:

public AccountController(UserManager<IdentityUser> userManager)

alors vous obtiendrez cette erreur:

InvalidOperationException: impossible de résoudre le service pour le type «Microsoft.AspNetCore.Identity.UserManager» 1 [IdentityUser] »

car vous avez utilisé ApplicationUserau démarrage, pas IdentityUsersi ce type n'est pas enregistré avec le système d'injection.

Greg Gum
la source
6
Cela compte pour toutes les références, donc si vous implémentez la nouvelle identité Razor pour asp.net core 2.1 pour remplacer votre ancien système d'identité, vous devez remplacer leur implémentation automatique de trucs comme SignInManager <IdentityUser> par SignInManager <ApplicationUser> partout où il est utilisé. Cela peut être ennuyeux. Vous devez également
réacheminer
14

C'est un peu sans rapport avec le message d'origine, mais puisque Google vous amène ici ... si vous obtenez cette erreur et que vous utilisez:

services.AddIdentityCore<YourAppUser>()

Ensuite, vous devrez enregistrer manuellement ce qui le AddIdentityfait, qui peut être trouvé ici: 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>>();

Vous devrez remplacer TUseret TRoleavec vos implémentations de ceux-ci, ou la valeur par défaut IdentityUser,IdentityRole

Serj Sagan
la source
J'ai dû créer un SignInManager personnalisé et cela a résolu le problème, si vous prévoyez de le faire, vérifiez github.com/dotnet/docs/issues/14828
perustaja
J'ai commencé par cette voie, mais j'ai trouvé la solution ici ( stackoverflow.com/a/60752194/1146862 ) plus simple; Le seul changement que j'ai dû faire (après la réorganisation AddIdentityet a AddJwtBearerété de définir les trois options indiquées dans l'exemple; je n'utilisais que DefaultAuthenticationScheme. Je récupère toujours le cookie à la connexion, mais [Authorize]fonctionne maintenant pour les jetons JWT sans spécifier de AuthenticationSchema.
Aaron
4

n'oubliez pas d'ajouter un gestionnaire de rôles dans ConfigureServices

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

Vous pouvez définir individuellement IdentityUser et IdentityRole dans ConfigureServices à l'intérieur de la classe Startup, comme indiqué ci-dessous:

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

OU

vous pouvez configurer directement dans AddIdentity:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
Mahavirsinh Padhiyar
la source
4
Avec une réponse de code uniquement, OP et d'autres apprendront à peine le problème, envisagez de modifier votre réponse et d'ajouter une explication
Cleptus
0

Si vous utilisez "IdentityServer", IdentityServer authentifie l'utilisateur et autorise le client. Par défaut, IdentityServer ne concerne pas la gestion des utilisateurs. Mais il existe un support pour asp.net Identity

Vous devez donc ajouter:

services.AddIdentityServer()
    .AddAspNetIdentity<ApplicationUser>();
Amirhossein Yari
la source
0

Vous devez mettre à jour votre classe Statup.cs avec ci-dessous

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

Ici: ApplicationUser est ma classe de modèle personnalisé.

Gaurav Joshi
la source