首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ASP.NET核心标识在应用程序启动时添加自定义用户角色

ASP.NET核心标识在应用程序启动时添加自定义用户角色
EN

Stack Overflow用户
提问于 2016-10-08 23:35:55
回答 3查看 12.8K关注 0票数 20

在ASP.NET核心应用程序中,我希望创建某些角色作为管理不同用户权限的基础。可悲的是,文档通知详细说明了如何在控制器/操作中使用自定义角色,但没有详细说明如何创建它们。我发现我可以使用RoleManager<IdentityRole>来解决这个问题,当实例的定义和ASP.NET核心标识在应用程序中注册时,它会自动注入到控制器构造函数中。

这让我可以添加一个自定义角色,如下所示:

代码语言:javascript
复制
var testRole = new IdentityRole("TestRole");
if(!roleManager.RoleExistsAsync(testRole.Name).Result) {
    roleManager.CreateAsync(testRole);
}

它可以工作并在数据库中创建角色。但是这种检查总是会在数据库上产生开销,调用特定的控制器/操作。因此,我希望在应用程序启动后检查一次自定义角色是否存在并添加它们。对于这一点,Startup.cs中的ConfigureServices方法似乎很好用。

但是:如何创建RoleManager<IdentityRole>类的实例来执行此操作?我想在这里使用一种最佳实践方法,而不是自己创建依赖实例,这似乎会导致很多工作,因为它没有很好的文档记录,并且肯定不会遵循最佳实践,因为ASP.NET核心正在使用依赖注入来做这样的事情(这在我的观点中也是合理的)。

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

EN

回答 3

Stack Overflow用户

发布于 2016-10-09 00:38:35

下面是一个在启动时迁移和播种数据库的示例:

创建一个静态类:

代码语言:javascript
复制
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));
                    }
                }
            }
        }
    }
}

Startup.cs

代码语言:javascript
复制
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...

    RolesData.SeedRoles(app.ApplicationServices).Wait();
}
票数 27
EN

Stack Overflow用户

发布于 2017-04-19 06:57:42

我倾向于仅在数据库中没有插入任何角色的情况下才对数据进行种子设置。换句话说,仅当应用程序第一次运行时才存储角色:

代码语言:javascript
复制
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));
                    }
                }
            }

        }
    }
}

在Startup.cs上:

代码语言:javascript
复制
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...

    RolesData.SeedRoles(app.ApplicationServices).Wait();
}
票数 6
EN

Stack Overflow用户

发布于 2021-06-06 03:51:47

如果有人来这里寻找.NET 5的解决方案,这里就是:

除了Configure方法中的一小部分之外,一切都与@Millan Sanchez的答案几乎相同……

我得到的是

代码语言:javascript
复制
One or more errors occurred. (Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.RoleManager`1[Microsoft.AspNetCore.Identity.IdemtityRole]' from root provider.)' 

在又搜索了一下之后,我发现了这个StackOverflow answer

实际上,我所需要做的就是将IServiceProvider添加到Configure方法的参数中,并将其传递到我对SeedUsers而不是app.applicationServices的调用中

完整代码:

代码语言:javascript
复制
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));
                    }
                }
            }

        }
    }
}

在Startup.cs上:

代码语言:javascript
复制
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
IServiceProvider serviceProvider)
{
    ...

    RolesData.SeedRoles(serviceProvider).Wait();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39934201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档