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>();
我对 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>();