Asp.net core ASP.NET Core 2.2创建标识用户
ASP.Net核心是全新的。必须创建具有标识的asp.net core 2.2项目(并为用户设定种子) 我找不到任何关于如何做到这一点的文档 我能够找到创建身份角色的代码(不管怎样编译,我还没有找到可以运行它的地方:Asp.net core ASP.NET Core 2.2创建标识用户,asp.net-core,identity,seeding,asp.net-core-identity,usermanager,Asp.net Core,Identity,Seeding,Asp.net Core Identity,Usermanager,ASP.Net核心是全新的。必须创建具有标识的asp.net core 2.2项目(并为用户设定种子) 我找不到任何关于如何做到这一点的文档 我能够找到创建身份角色的代码(不管怎样编译,我还没有找到可以运行它的地方: private static async Task CreateUserTypes(ApplicationDbContext authContext, IServiceProvider serviceProvider) { var RoleManager = se
private static async Task CreateUserTypes(ApplicationDbContext authContext, IServiceProvider serviceProvider)
{
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
string[] roleNames = { "Administrator", "Data Manager", "Interviewer", "Respondent" };
IdentityResult roleResult;
foreach (var roleName in roleNames)
{
var roleExist = await RoleManager.RoleExistsAsync(roleName);
if (!roleExist)
{
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
}
我们将研究CreateUserManager的其他参数是什么,以及如何从serviceProvider获取这些参数
--欧文
找到了解决方法。关键是找到正确的服务提供商来传递和创建用户管理器的正确语法。我通过谷歌找到的其他答案都是用他们自己的应用程序用户来替换标识用户
,这让事情变得一团糟。下面是我的工作ng功能(希望这对某人有帮助):
private静态异步任务CreateRootUser(Models.CensORContext上下文、ApplicationDbContext authContext、IServiceProvider服务提供者)
{
//为all things ADMIN创建根管理员用户。
var userStore=新的userStore(authContext);
UserManager UserManager=serviceProvider.GetRequiredService();
//新的用户管理器(userStore,null,null,null,null,null,null,serviceProvider,null);
//=serviceProvider.GetRequiredService();
IdentityUser用户=新IdentityUser()
{
用户名=”admin@admin.admin",
电子邮件=”admin@admin.admin"
};
var result=await userManager.CreateAsync(用户,“密码”);
结果=wait userManager.AddToRoleAsync(用户,“管理员”);
}
您的主要问题似乎是依赖项注入。有关详细信息,请查看。只要您以正确的方式注入DbContext
和UserManager
,其余的代码就可以了
下面是一个例子。您可以为种子设定单独的服务,以确保您的代码与其他代码分离
public class UserSeeder
{
private readonly UserManager<IdentityUser> userManager;
private readonly ApplicationDbContext context;
public UserSeeder(UserManager<IdentityUser> userManager, ApplicationDbContext context)
{
this.userManager = userManager;
this.context = context;
}
public async Task `()
{
string username = "admin@admin.admin";
var users = context.Users;
if (!context.Users.Any(u => u.UserName == username))
{
var done = await userManager.CreateAsync(new IdentityUser
{
UserName = username,
Email = username
}, username);
}
}
}
请注意,这两种方法都是每次调用数据库。您可以计划将其放置在何处。您还可以确保在布尔值的帮助下(可以是单例)只调用一次。但请注意,这只会在应用程序启动时运行。以下是我为管理用户设定种子的方法(从《EF核心行动》一书中学习):
这是用户
类:
public class User : IdentityUser<long>
{
//add your extra properties and relations
}
public class Role : IdentityRole<long>
{
public static string Admin = "Admin";
}
它可以是空的,我使用静态字符串来避免代码中的魔法字符串
这是DbContext
:
public class ApplicationDbContext : IdentityDbContext<User, Role, long>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{ }
//your DbSets and configurations
//...
}
这是种子数据的扩展方法:
public static class SeedData
{
public static IWebHost SeedAdminUser(this IWebHost webHost)
{
using (var scope = webHost.Services.CreateScope())
{
try
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
context.Database.EnsureCreated();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<Role>>();
if (!userManager.Users.Any(u => u.Email == "admin@domain.com"))
{
roleManager.CreateAsync(new Role()
{
Name = Role.Admin
})
.Wait();
userManager.CreateAsync(new User
{
UserName = "Admin",
Email = "admin@domain.com"
}, "secret")
.Wait();
userManager.AddToRoleAsync(userManager.FindByEmailAsync("admin@domain.com").Result, Role.Admin).Wait();
}
}
catch (Exception ex)
{
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding user.");
//throw;
}
}
return webHost;
}
}
我理解在试图让代码正常工作时的挫折感,尤其是在时间紧迫的情况下。我也理解大声喊出来的诱惑。我们都有过这样或那样的经历。虽然您的问题确实传达了您的编码问题是什么,但在发布问题时请尽量保持冷静。这样,所有人都会更加关注您的编程问题。您是否使用个人用户的默认模板创建了新项目?我建议您添加最后一段,似乎是工作代码,作为您的答案,并将其从中删除问题看一看。这似乎是你真正的问题所在,而不是身份。这将有助于更好地理解这个概念。stackOverflow不会让我发布答案(没有足够的声誉点数)-因此,我在答案中加入了我的工作代码。我相信还有更好的方法可以做到这一点…谢谢大家的评论和帮助。我将努力降低我的沮丧情绪-当周围没有人时,很容易大声喊叫…谢谢。这是一个很好的方法,信息量很大,但是有两个建议。首先,不要使用GetRequiredService
对于每个服务,如果您创建一个单独的类并将其用作服务,它将更干净、更灵活。其次,您可以在startup中的Configure
函数上运行它,而不是创建扩展并在program.cs上运行(代码更像是startup的工作)。我还发现前三组代码实际上与问题不相关。Configure
方法中的代码将针对每个请求运行。种子数据在应用程序启动期间只应出现一次。不完全如此。Configure
方法仅调用一次。函数中创建的中间件将针对每个请求调用一次请求。我说的是调用configure内部的SeedAdminUser
,而不是创建中间件。我如何“在主控制器中注入UserSeeder”?-或者-我应该将“app.Use(..”放在哪里因此,我有一个上下文,等等。要注入控制器或任何服务,您需要将其作为构造函数参数public home controller(UserSeeder UserSeeder)
传递。基本上,与我将UserManager
注入控制器中的UserSeeder
的方式相同。app.Use(
在Startup
类中的Confugure
函数的开头。啊……这个注入功能非常强大,我已经习惯了不同的语法。你有没有推荐一个blog/blog/course/等来了解如何使用它(不一定是它如何工作或如何构建它)?
public class User : IdentityUser<long>
{
//add your extra properties and relations
}
public class Role : IdentityRole<long>
{
public static string Admin = "Admin";
}
public class ApplicationDbContext : IdentityDbContext<User, Role, long>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{ }
//your DbSets and configurations
//...
}
public void ConfigureServices(IServiceCollection services)
{
//...
services.AddIdentity<User, Role>(options =>
{
//you can configure your password and user policy here
//for example:
options.Password.RequireDigit = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
//...
}
public static class SeedData
{
public static IWebHost SeedAdminUser(this IWebHost webHost)
{
using (var scope = webHost.Services.CreateScope())
{
try
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
context.Database.EnsureCreated();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<User>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<Role>>();
if (!userManager.Users.Any(u => u.Email == "admin@domain.com"))
{
roleManager.CreateAsync(new Role()
{
Name = Role.Admin
})
.Wait();
userManager.CreateAsync(new User
{
UserName = "Admin",
Email = "admin@domain.com"
}, "secret")
.Wait();
userManager.AddToRoleAsync(userManager.FindByEmailAsync("admin@domain.com").Result, Role.Admin).Wait();
}
}
catch (Exception ex)
{
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while seeding user.");
//throw;
}
}
return webHost;
}
}
CreateWebHostBuilder(args)
.Build()
.SeedAdminUser()
.Run();