c# - 如何在 ASP.NET Core 2.2 中实现标识
问题描述
在我的网站中,我想让管理员使用帐户登录以修改数据库。另外,我将来可能会添加一些角色和帐户。
所以,我正在尝试实现identity。
我在 Visual Studio 2019 中创建了一个项目(不确定这是否重要),并选择了带有 MVC 的 ASP.NET Core 2.2(我自己安装了 Core 2.2),使用个人用户帐户进行身份验证,然后我点击了上面写着的框:“配置 HTTPS”。
制作项目后,我打开它,创建一个随机帐户,出现错误,然后迁移数据库以修复它。
然后,我添加appsetting.json
:
"UserSettings": {
"UserName": "MyAdminUser",
"UserEmail": "MyAdminUser@gmail.com",
"UserPassword": "A_123456a"
}
在文件夹中创建一个新类Data
:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace WebApplication1.Data {
public static class Seed {
public static async Task CreateRoles(IServiceProvider serviceProvider, IConfiguration Configuration) {
// Add customs roles
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
// Note: I used IdentityUser instead of make my ApplicationUser as other people do because the default idendity is fine for me, I don't need additional fields nor I want to make this more difficult.
var UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
string[] roleNames = { "Admin" };
IdentityResult roleResult;
foreach (var roleName in roleNames) {
// Create roles and seeding them to the database
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (!roleExist) {
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
// Create a super user
var poweruser = new IdentityUser {
UserName = Configuration.GetSection("AppSettings")["UserSettings:UserName"],
Email = Configuration.GetSection("AppSettings")["UserSettings:UserEmail"]
};
string userPassword = Configuration.GetSection("AppSettings")["UserSettings:UserPassword"];
var user = await UserManager.FindByEmailAsync(Configuration.GetSection("AppSettings")["UserSettings:UserEmail"]);
if (user == null) {
var createPowerUser = await UserManager.CreateAsync(poweruser, userPassword);
if (createPowerUser.Succeeded) {
// Assign the new user the "Admin" role
await UserManager.AddToRoleAsync(poweruser, "Admin");
}
}
}
}
}
最后将类的Main
方法替换Program
为:
public static void Main(string[] args) {
var host = CreateWebHostBuilder(args).Build();
using (var scope = host.Services.CreateScope()) {
var services = scope.ServiceProvider;
var serviceProvider = services.GetRequiredService<IServiceProvider>();
var configuration = services.GetRequiredService<IConfiguration>();
Seed.CreateRoles(serviceProvider, configuration).Wait();
}
host.Run();
}
但是当我运行它时,HTTP Error 500.30 - ANCM In-Process Start Failure
网页上会出现错误,并且调试控制台显示以下异常:
'System.InvalidOperationException' in Microsoft.Extensions.DependencyInjection.Abstractions.dll
'System.AggregateException' in System.Private.CoreLib.dll
我不知道如何解决这个问题。
此外,我发现了所有这些问题(及其答案)1、2、3、4、5、6以及这些 Non-SO 7和8。但我对它们的主要问题是每个人都使用不同的方式来实现身份(其中一些已经过时到 2.2)而且我不知道哪个更好,甚至在我的项目中出现一些错误或者我不明白根本没有,所以我尝试这样做(我读到执行此代码比执行此代码Program
要好Startup
)。
顺便说一句,我还尝试从参数中删除我的代码Programm
,而是从参数中添加Configure
方法,并且:Startup
IServiceProvider serviceProvider
// I used _ = because VS said me something about async
_ = Seed.CreateRoles(serviceProvider, Configuration);
解决方案
问题是您试图在IServiceProvider
不创建范围的情况下从中检索范围服务。有趣的是,您在对 的调用周围创建了一个范围Seed.CreateRoles
,但随后您传入了IServiceProvider
没有范围的 。
你应该做的是要么传入并在你的方法中IServiceProvider
创建范围,要么将范围创建留在现在的位置,而是传入你的范围服务,即和.Seed.CreateRoles
RoleManager
UserManager
编辑
您需要执行以下操作之一:
在种子方法中注入
IServiceProvider
然后创建你的作用域:var host = CreateWebHostBuilder(args).Build(); Seed.CreateRoles(host.Services); host.Run();
然后:
public static async Task CreateRoles(IServiceProvider services) { var configuration = services.GetRequiredService<IConfiguration>(); using (var scope = services.CreateScope()) { var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>(); var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>(); // seed data } }
注入您的范围服务:
var host = CreateWebHostBuilder(args).Build(); var configuration = host.Services.GetRequiredService<IConfiguration>(); using (var scope = host.Services.CreateScope()) { var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>(); var userManager = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>(); Seed.CreateRoles(configuration, roleManager, userManager); } host.Run();
推荐阅读
- c# - XPath 查找在其间跳过未知层数的元素
- java - 如何在 Hibernate 投影中映射嵌套集合
- html - 如何使用 xpath 通过搜索该元素旁边的文本来定位该元素
- c# - Unity c# - 在 VN 风格游戏中管理角色精灵/图像
- javascript - 如何使用 jQuery 上传多个 PDF 文件?
- html - 如果太大,将 div 的内容分成多列
- java - 当两者都启用 mTLS 时,Spring Cloud Config Client 和 Server 存在先有鸡还是先有蛋的问题?
- flutter - 无法在 Flutter Personal Expenses App 中本地保存
- python-3.x - 如何使两个相同的networkx图具有相同的节点顺序
- python - Soap 请求在 Soapui 中运行良好,但在 python 中运行良好 - ZEEP - SUDS