Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No service for type 'Microsoft.AspNetCore.Identity.RoleManager error

I'm setting up user roles on a ASP.NET CORE 2.1 application. But when I try to use the RoleManager it shoots into error. The error I get is:

No service for type 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]' has been registered.)'

I've looked through the whole application to see if IdentityUser is still anywhere, since I've created a class that inherits from it ( ApplicationUser ), but everything else seems correct. Adding services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); gives a runtime error stating: NotSupportedException: Store does not implement IUserRoleStore<TUser>. Adding Service.AddDefaultIdentity()instead of AddIdentity()doesn't work either.

public class Startup
{

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        //services.AddDbContext<ApplicationDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ApplicationDBContextConnection")));


        //services.AddDefaultIdentity<ApplicationUser>().AddRoles<IdentityRole>().AddEntityFrameworkStores<ApplicationDBContext>();

        services.Configure<IdentityOptions>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = true;
            options.Password.RequireLowercase = false;
            options.Password.RequiredUniqueChars = 6;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 10;
            options.Lockout.AllowedForNewUsers = true;

            // User settings
            options.User.RequireUniqueEmail = true;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, UserManager<ApplicationUser> userManager)
    {


        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();
        app.UseAuthentication();


        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

        CreateUserRoles(userManager).GetAwaiter().GetResult();
    }
    private async Task CreateUserRoles( UserManager<ApplicationUser> userManager)
    {

        var UserManager = userManager;

        //Assign Admin role to the main User here we have given our newly registered 
        //login id for Admin management
        ApplicationUser user = await UserManager.FindByEmailAsync("[email protected]");
        UserManager.AddToRoleAsync(user, "Admin").GetAwaiter().GetResult();
    }
}
like image 231
Carlove Avatar asked Feb 06 '19 20:02

Carlove


People also ask

What is Microsoft Aspnetcore identity?

ASP.NET Core Identity: Is an API that supports user interface (UI) login functionality. Manages users, passwords, profile data, roles, claims, tokens, email confirmation, and more.

What is AddEntityFrameworkStores?

AddEntityFrameworkStores<TContext>(IdentityBuilder)Adds an Entity Framework implementation of identity information stores. C# Copy.

What is UserManager ASP NET core?

There are two core services of the Identity framework, one is the UserManager, and the other is the SignInManager. We need to inject both of these services into our controller. With this, we can call the appropriate APIs when we need to create a user or sign in a user.


2 Answers

I have figured it out.

I created a new ApplicationUser class, which inherited from it IdentityUser. Afterwards I ran the Identity scaffolder, stating to use my ApplicationUser as the new class.

While doing that .NET CORE created an additional class:

    public class IdentityHostingStartup : IHostingStartup
{
    public void Configure(IWebHostBuilder builder)
    {
        builder.ConfigureServices((context, services) => {
            services.AddDbContext<ApplicationDBContext>(options =>
                options.UseSqlServer(
                    context.Configuration.GetConnectionString("ApplicationDBContextConnection")));

            services.AddDefaultIdentity<ApplicationUser>()
                .AddEntityFrameworkStores<ApplicationDBContext>();
        });
    }
}

The configuration in this class overrides every option and service ( that has been declared ) in the startup class. And it will crash if you have identical options/services declared in both classes.. That's why It wasn't working. After adding .AddRoles<IdentityRole>() to the IdentityHostingStartUp everything is working!

I'm still looking for a way to rip out the IdentityHostingStartUp, just ripping out those declared there will let the application crash.

like image 20
Carlove Avatar answered Sep 27 '22 17:09

Carlove


You can inject any registered service explicitly into the Configure() method.

public void Configure(RoleManager<IdentityRole> roleManager)

I'm not sure what is happening when you try to inject IServiceProvider, but it doesn't look correct.

Also, never use .Wait(), use .GetAwaiter().GetResult() instead.

like image 61
Brad M Avatar answered Sep 27 '22 18:09

Brad M