ASP.NET Core 2 - 身份 - 自定义角色的 DI 错误

Posted

技术标签:

【中文标题】ASP.NET Core 2 - 身份 - 自定义角色的 DI 错误【英文标题】:ASP.NET Core 2 - Identity - DI errors with custom Roles 【发布时间】:2018-01-30 00:39:29 【问题描述】:

我的 Startup.cs 中有这段代码:

 services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, ApplicationRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

在同一个文件中,我还按照 MS 在新版本 ASP Core 2 中的建议将 service.UseIdentity() 替换为 app.UseAuthentication();

我的数据库上下文:

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    
    

    protected override void OnModelCreating(ModelBuilder builder)
    
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    


    //public DbSet<ApplicationUser> ApplicationUser  get; set; 

    //public DbSet<ApplicationRole> ApplicationRole  get; set; 

还有我的自定义角色类:

 public class ApplicationRole : IdentityRole

    public ApplicationRole() : base()  

    public ApplicationRole(string roleName) : base(roleName)  

    public bool IsDefault  get; set; 

运行应用程序时,我得到了一个运行的 SeedDatabase 辅助方法:

var roleManager = serviceProvider.GetService<RoleManager<ApplicationRole>>();

一切正常,但自从将 VS 2017 更新到最新版本并安装 .NET Core 2.0 后,这最后一行代码现在引发以下异常:

System.AggregateException occurred
HResult=0x80131500
Message=One or more errors occurred. (Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.RoleManager`1[CspLicensingPortal.Models.ApplicationRole]' from root provider.)
Source=<Cannot evaluate the exception source>
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at CspLicensingPortal.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) in D:\gsandorx\Documents\Visual Studio 2017\Projects\CspLicensingPortal\CspLicensingPortal\Startup.cs:line 275

Inner Exception 1:
InvalidOperationException: Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.RoleManager`1[MyApplication.Models.ApplicationRole]' from root provider.

我不确定为什么 DI 服务管理器不再能够找到我的 ApplicationRole 类。我已经检查过,我所有的引用都在使用这个类,而不是默认的 IdentityRole。

有什么想法吗?

【问题讨论】:

【参考方案1】:

您必须自己创建 IServiceScope。

要做到这一点,你必须更换

var roleManager = serviceProvider.GetService<RoleManager<ApplicationRole>>();

using (IServiceScope scope = app.ApplicationServices.CreateScope()) 
    RoleManager<IdentityRole> roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();

    // Seed database code goes here

【讨论】:

谢谢!我猜在 2.0 中发生了很多变化,并且文档仍然在纸尿裤中 :) 不是尿布,更像是垃圾桶。我对最新版本的 .NET Core 团队感到非常失望。真可怜。 @Manos,非常感谢您的回答。疯狂的是,当我想到 .NET Core 团队认为添加更多代码行来执行需要一行代码的功能时,我嘴里吐了一点。再次,非常失望(根据我上面的评论) @Keith 为您的服务创建一个范围是有意义的,所以我可以接受额外的代码。但正如你所说,它应该有更好的记录。 这仍然是个问题,因为您必须在作用域内播种。如果我想调用一个不同的类来播种数据,范围变量(对于 ex roleManager)被释放。

以上是关于ASP.NET Core 2 - 身份 - 自定义角色的 DI 错误的主要内容,如果未能解决你的问题,请参考以下文章

ASP.Net Core 2.1 中的身份< - 自定义 AccountController

如何从 ASP.NET Core 2.0 中的自定义中间件请求身份验证

asp.net core系列 48 Identity 身份模型自定义

从 ASP.NET Core 1.1 MVC 迁移到 2.0 后,自定义 cookie 身份验证不起作用

ASP.Net-Core 中的自定义身份验证

asp.Net core 2.2中的多种身份验证方法