ASP.NET CORE 2.1 身份已注册

ASP.NET CORE 2.1 Identity has been registered

我对 Identity ASP.net Core 2.1 有疑问。我在 startup.cs 中创建角色。 运行时显示错误

AggregateException: One or more errors occurred. (No service for type 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdentityRole]' has been registered.) System.Threading.Tasks.Task.Wait(int millisecondsTimeout, CancellationToken cancellationToken) System.Threading.Tasks.Task.Wait() ContosoUniversity.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider) in Startup.cs + CreateRoles(serviceProvider).Wait(); Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app) Microsoft.AspNetCore.Server.IISIntegration.IISSetupFilter+<>c__DisplayClass4_0.b__0(IApplicationBuilder app) Microsoft.AspNetCore.HostFilteringStartupFilter+<>c__DisplayClass0_0.b__0(IApplicationBuilder app) Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter+<>c__DisplayClass0_0.b__0(IApplicationBuilder builder) Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

Statup.cs 文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;
using Microsoft.AspNetCore.Identity;
using ContosoUniversity.Areas.Identity.Data;

namespace ContosoUniversity
{
    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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddDbContext<SchoolContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));

            //services.AddIdentity<ContosoUniversityUser, IdentityRole>()
            //    .AddEntityFrameworkStores<IdentityContext>()
            //     .AddDefaultTokenProviders();


        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseAuthentication();
            app.UseMvc();
            CreateRoles(serviceProvider).Wait();
        }
        public async Task CreateRoles(IServiceProvider serviceProvider)
        {

            //adding custom roles
            var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            //serviceProvider.GetService<RoleManager<IdentityRole>>();
            var UserManager = serviceProvider.GetRequiredService<UserManager<ContosoUniversityUser>>();
            string[] roleNames = { "Admin", "Manager", "Member" };
            IdentityResult roleResult;
            foreach (var roleName in roleNames)
            {
                var roleExist = await RoleManager.RoleExistsAsync(roleName);
                if (!roleExist)
                {
                    roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
                }
            }
            var poweruser = new ContosoUniversityUser
            {
                UserName = Configuration.GetSection("UserSettings")["UserEmail"],
                Email = Configuration.GetSection("UserSettings")["UserEmail"]
            };

            string UserPassword = Configuration.GetSection("UserSettings")["UserPassword"];
            var _user = await UserManager.FindByEmailAsync(Configuration.GetSection("UserSettings")["UserEmail"]);

            if (_user == null)
            {
                var createPowerUser = await UserManager.CreateAsync(poweruser, UserPassword);
                if (createPowerUser.Succeeded)
                {
                    await UserManager.AddToRoleAsync(poweruser, "Admin");
                }
            }
        }
    }
}

您正在尝试使用 asp.net-identity 而未在您的容器中注册它。

在配置服务方法中取消注释这些行

services.AddIdentity<ContosoUniversityUser, IdentityRole>();
        .AddEntityFrameworkStores<IdentityContext>()
        .AddDefaultTokenProviders();

现在服务提供商将知道这些服务,因为 extension method 为您注册了它们。

另外不要忘记迁移您的数据库,以便它了解用户、角色等。

您似乎 Identity 达到了 Asp.Net Core Identity Library

您可以检查您的项目以找到 ProjectName->Areas->Identity->IdentityHostingStartup。像下面这样更改 Configure

    public class IdentityHostingStartup : IHostingStartup
{
    public void Configure(IWebHostBuilder builder)
    {
        builder.ConfigureServices((context, services) => {
            services.AddDbContext<CoreAppContext>(options =>
                options.UseSqlServer(
                    context.Configuration.GetConnectionString("CoreAppContextConnection")));
            services.AddIdentity<ContosoUniversityUser, IdentityRole>()
                    .AddEntityFrameworkStores<CoreAppContext>();
        });
    }
}

更新

根本原因是services.AddDefaultIdentity没有在IServiceCollection中加入IdentityRole,查看源码IdentityServiceCollectionUIExtensions which call AddIdentityCore

试试下面的代码。

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

            services.AddDefaultIdentity<ContosoUniversityUser>()
                    .AddRoles<IdentityRole>() // Add IdentityRole to ServiceCollection
                    .AddEntityFrameworkStores<IdentityContext>();
        });
    }
}

我尝试在 ConfigureServices 中添加以下代码。这可以帮助我运行:

var builder = services.AddIdentityCore<ContosoUniversityUser>(opt =>
        {
            // Configure Password Options
            opt.Password.RequireDigit = true;
        }
        );
        builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);
        builder.AddRoleValidator<RoleValidator<IdentityRole>>();
        builder.AddRoleManager<RoleManager<IdentityRole>>();
        builder.AddSignInManager<SignInManager<ContosoUniversityUser>>();
        builder.AddEntityFrameworkStores<IdentityContext>().AddDefaultTokenProviders();

        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();