ASP.NET Core Identity在应用程序启动时添加自定义用户角色

Lio*_*ion 20 c# user-roles asp.net-core-mvc asp.net-core

在ASP.NET Core应用程序中,我想创建某些角色作为管理不同用户权限的基础.遗憾的是,文档告知详细说明如何使用自定义角色,例如在控制器/操作中,而不是如何创建它们.我发现我可以使用RoleManager<IdentityRole>此实例,当实例在应用程序中注册其定义的和ASP.NET Core身份时,会自动注入到控制器构造函数中.

这让我添加一个这样的自定义角色:

var testRole = new IdentityRole("TestRole");
if(!roleManager.RoleExistsAsync(testRole.Name).Result) {
    roleManager.CreateAsync(testRole);
}
Run Code Online (Sandbox Code Playgroud)

它在数据库中工作并创建角色.但是这种检查总是会在数据库上产生开销,调用特定的控制器/动作.所以我想在我的应用程序启动后检查一次,如果自定义角色存在并添加它们.ConfigureServicesStartup.cs中的方法似乎很适合.

但是:如何创建RoleManager<IdentityRole>类的实例呢?我想在这里使用最佳实践方法,而不是通过自己创建依赖实例来解决这个问题,这似乎会导致很多工作,因为它没有很好的文档化,并且肯定不会遵循最佳实践,因为ASP.NET Core正在使用依赖注入这样的事情(这在我的意见中也是合理的).

换句话说:我需要在控制器之外使用依赖注入.

tmg*_*tmg 27

以下是在启动时迁移和播种数据库的需求示例:

创建一个静态类:

public static class RolesData
{
    private static readonly string[] Roles = new string[] {"Administrator", "Editor", "Subscriber"};

    public static async Task SeedRoles(IServiceProvider serviceProvider)
    {
        using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var dbContext = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();

            if (dbContext.Database.GetPendingMigrations().Any())
            {
                await dbContext.Database.MigrateAsync();

                var roleManager = serviceScope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();

                foreach (var role in Roles)
                {
                    if (!await roleManager.RoleExistsAsync(role))
                    {
                        await roleManager.CreateAsync(new IdentityRole(role));
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并在Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...

    RolesData.SeedRoles(app.ApplicationServices).Wait();
}
Run Code Online (Sandbox Code Playgroud)


小智 6

我希望仅在数据库中没有插入角色时才播种数据.换句话说,仅在应用程序第一次运行时才存储角色:

public static class RolesData
{
    private static readonly string[] Roles = new string[] { "Administrator", "Editor", "Subscriber" };

    public static async Task SeedRoles(IServiceProvider serviceProvider)
    {
        using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var dbContext = serviceScope.ServiceProvider.GetService<AppDbContext>();

            if (!dbContext.UserRoles.Any())
            {
                var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();

                foreach (var role in Roles)
                {
                    if (!await roleManager.RoleExistsAsync(role))
                    {
                        await roleManager.CreateAsync(new IdentityRole(role));
                    }
                }
            }

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在Startup.cs上:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...

    RolesData.SeedRoles(app.ApplicationServices).Wait();
}
Run Code Online (Sandbox Code Playgroud)