基于 Blazor 角色的授权 - 类型 'Microsoft.AspNetCore.Identity.RoleManager' 没有服务

Blazor Role based Authorization - No service for type 'Microsoft.AspNetCore.Identity.RoleManager'

我正在使用 GitHub 的一个免费项目,该项目将 Blazor 与 EF Identity 和 SQLite 结合使用。它是我学习和添加更多功能的良好起点。目前,我想为项目添加授权以允许特定用户访问特定页面。我的第一步是添加默认角色和帐户。我设法找到了一些在启动期间执行此操作的示例代码。但是,我收到以下运行时错误。

我在互联网上搜索示例代码和修复程序。不幸的是,无论我用我对 ASP.NET 的有限知识做什么,它都不起作用。这是我的启动代码。我在项目中添加了CreateRoles功能,其余不变

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
              options.UseSqlite("Filename=data.db"));

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

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings
                options.Password.RequireDigit = false;
                options.Password.RequiredLength = 6;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                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 = false;
            });

            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });

            services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.HttpOnly = false;
                options.Events.OnRedirectToLogin = context =>
                {
                    context.Response.StatusCode = 401;
                    return Task.CompletedTask;
                };
            });

            services.AddControllers().AddNewtonsoftJson();
            services.AddResponseCompression(opts =>
            {
                opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
                    new[] { "application/octet-stream" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider service)
        {
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetService<ApplicationDbContext>().Database.Migrate();
            }

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebAssemblyDebugging();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
                endpoints.MapFallbackToFile("index.html");
            });

            CreateRoles(service).GetAwaiter().GetResult();
        }

        private async Task CreateRoles(IServiceProvider serviceProvider)
        {
            //initializing custom users and roles   
            var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            var UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
            string[] roleNames = { "Admin", "User", "HR" };
            IdentityResult roleResult;

            foreach (var roleName in roleNames)
            {
                var roleExist = await RoleManager.RoleExistsAsync(roleName);
                if (!roleExist)
                {
                    //create the roles and seed them to the database: Question 1  
                    roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
                }
            }

            IdentityUser user = await UserManager.FindByEmailAsync("admin@gmail.com");

            if (user == null)
            {
                user = new IdentityUser()
                {
                    UserName = "admin",
                    Email = "admin@gmail.com",
                };
                await UserManager.CreateAsync(user, "Passwd@12");
            }

            bool role = await UserManager.IsInRoleAsync(user, "Admin");
            if (!role)
            {
                await UserManager.AddToRoleAsync(user, "Admin");
            }

        }
    }

可以在 GitHub 的 BlazorWithIdentity 上找到该项目。我希望能够创建角色,以便我可以在此项目中使用 AuthorizeView。非常感谢您的帮助。

您的问题在 CreateRoles 中:

//initializing custom users and roles   
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();

替换为:

//initializing custom users and roles   
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole<Guid>>>();
var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

因为你用 :

注册了一个 RoleManager<IdentityRole<Guid>> 和一个 UserManager<ApplicationUser>
services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()

您需要添加.AddRoles<IdentityRole>()

    services.AddIdentity<ApplicationUser, IdentityRole<Guid>>()
                .AddRoles<IdentityRole>()                
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();