简体   繁体   English

将 AddPooledDbContextFactory 与 AspNetCore.Identity 一起使用

[英]Using AddPooledDbContextFactory with AspNetCore.Identity

I've got asp.net core webapi app which currently uses Microsoft.AspNetCore.Identity and services.AddDbContext in ConfigureServices methods in Startup class and everything works so far.我有 asp.net 核心 webapi 应用程序,它目前在Startup class 的ConfigureServices方法中使用Microsoft.AspNetCore.Identityservices.AddDbContext ,到目前为止一切正常。

I tried to use services.AddPooledDbContextFactory instead of services.AddDbContext to improve performance.我尝试使用services.AddPooledDbContextFactory而不是services.AddDbContext来提高性能。 However when I try to use AddPooledDbContextFactory I've got an error:但是,当我尝试使用AddPooledDbContextFactory时出现错误:

System.InvalidOperationException: Unable to resolve service for type 'hostapp.Data.DataContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore 5[hostapp.Models.AppRole,hostapp.Data.DataContext,System.Int32,hostapp.Models.AppUserRole,Microsoft.AspNetCore.Identity.IdentityRoleClaim 1[System.Int32]]' System.InvalidOperationException:尝试激活“Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore 5[hostapp.Models.AppRole,hostapp.Data.DataContext,System.Int32,hostapp.Models.AppUserRole,Microsoft.AspNetCore.Identity.IdentityRoleClaim时无法解析类型“hostapp.Data.DataContext”的服务5[hostapp.Models.AppRole,hostapp.Data.DataContext,System.Int32,hostapp.Models.AppUserRole,Microsoft.AspNetCore.Identity.IdentityRoleClaim 1[System.Int32]]'

After seeing this error I created new webapi project which uses AddPooledDbContextFactory without Microsoft.AspNetCore.Identity which works fine.看到这个错误后,我创建了新的 webapi 项目,它使用AddPooledDbContextFactory而没有Microsoft.AspNetCore.Identity工作正常。 So my question is:所以我的问题是:

What is the proper way of using services.AddPooledDbContextFactory with Microsoft.AspNetCore.Identity to avoid error above?services.AddPooledDbContextFactoryMicrosoft.AspNetCore.Identity一起使用以避免上述错误的正确方法是什么?

in ProjectRoot/Startup.csProjectRoot/Startup.cs

using System.Threading.Tasks;
using hostapp.Data;
using hostapp.GraphQL;
using hostapp.Interfaces;
using hostapp.Models;
using hostapp.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace hostapp
{
    public class Startup
    {
        
        // ...
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<ICookieService, CookieService>();
            
            // EARLIER IMPLEMENTATION WHICH WORKS FINE =>
            // services.AddDbContext<DataContext>(options =>
            // {
            //     options.UseSqlServer(_config.GetConnectionString("DefaultConnection"));
            // });

            // CURRENT IMPLEMENTATION WHICH CAUSES AN ERROR
            services.AddPooledDbContextFactory<DataContext>(options =>
            {
                options.UseSqlServer(_config.GetConnectionString("DefaultConnection"));
            });

            services.AddIdentityCore<AppUser>(opt =>
            {
                opt.Password.RequireNonAlphanumeric = false;
            })
            .AddRoles<AppRole>()
            .AddRoleManager<RoleManager<AppRole>>()
            .AddSignInManager<SignInManager<AppUser>>()
            .AddRoleValidator<RoleValidator<AppRole>>()
            .AddEntityFrameworkStores<DataContext>();

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.Cookie.Name = "app-cookie";
                // options.Cookie.Expiration = TimeSpan.FromMinutes(30);
                options.Events.OnRedirectToLogin = context =>
                {
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    return Task.CompletedTask;
                };
            });

            services.AddAuthorization(opt =>
            {
                opt.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
            });

            services
                .AddGraphQLServer()
                .AddAuthorization()
                .AddQueryType<Query>();

            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseCors(options => options
                .AllowAnyHeader()
                .AllowAnyMethod()
                .WithOrigins("https://localhost:4200")
                .SetIsOriginAllowed(origin => true)
                .AllowCredentials());

            app.UseCookiePolicy(new CookiePolicyOptions
            {
                MinimumSameSitePolicy = SameSiteMode.Strict,
                // HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always,
                // Secure = CookieSecurePolicy.Always
            });

            app.UseAuthentication();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapGraphQL();
            });
        }
    }
}

in ProjectRoot/Data/DataContext.csProjectRoot/Data/DataContext.cs

using hostapp.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace hostapp.Data
{
    public class DataContext : IdentityDbContext<AppUser, AppRole, int,
                               IdentityUserClaim<int>, AppUserRole, IdentityUserLogin<int>,
                               IdentityRoleClaim<int>, IdentityUserToken<int>>
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options)
        {
        }

        public DbSet<AppUserClaim> Claims { get; set; }
        public DbSet<AppUserClaimOffender> Offenders { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<AppUser>()
                .HasMany(ur => ur.AppUserRoles)
                .WithOne(u => u.AppUser)
                .HasForeignKey(ur => ur.UserId)
                .IsRequired();

            builder.Entity<AppRole>()
                .HasMany(ur => ur.AppUserRoles)
                .WithOne(u => u.AppRole)
                .HasForeignKey(ur => ur.RoleId)
                .IsRequired();
        }
    }
}

in ProjectRoot/app.csprojProjectRoot/app.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0"/>
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0" NoWarn="NU1605"/>
    <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.0" NoWarn="NU1605"/>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3"/>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0"/>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.0"/>
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.0"/>
    <PackageReference Include="HotChocolate.AspNetCore" Version="11.1.0"/>
    <PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="11.1.0"/>
    <PackageReference Include="HotChocolate.Data.EntityFramework" Version="11.1.0"/>
    <PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0"/>
  </ItemGroup>
</Project>

What is the proper way of using services.AddPooledDbContextFactory with Microsoft.AspNetCore.Identity to avoid error above?将 services.AddPooledDbContextFactory 与 Microsoft.AspNetCore.Identity 一起使用以避免上述错误的正确方法是什么?

In the ConfigureServices, try to use AddScoped() method to register the DBContext and use the provider to get the factory from the services.在 ConfigureServices 中,尝试使用 AddScoped() 方法注册 DBContext 并使用提供者从服务中获取工厂。 Then, return the instance to the provider.然后,将实例返回给提供者。 The code like this:像这样的代码:

        services.AddPooledDbContextFactory<DataContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
            options.EnableSensitiveDataLogging();
        }, poolSize:32);

        services.AddScoped<DataContext>(p => p.GetRequiredService<IDbContextFactory<DataContext>>().CreateDbContext());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AspNetCore.Identity中的Google身份验证 - Google authentication in AspNetCore.Identity 覆盖AspNetCore.Identity表中的默认索引 - Override default indexes in AspNetCore.Identity tables AspNetCore.Identity LockoutOptions.AllowedForNewUsers属性 - AspNetCore.Identity LockoutOptions.AllowedForNewUsers Property ViewComponent 无法识别 AspNetCore.Identity“用户” - ViewComponent does not recognize AspNetCore.Identity "User" 在界面中使用 AspNetCore.Identity RoleManager 和 UserManager - Use AspNetCore.Identity RoleManager and UserManager in an Interface 使用 aspnetcore.identity 时“发现不同版本之间存在冲突”或 System.MissingMethodException - "Found conflicts between different versions" OR System.MissingMethodException when using aspnetcore.identity 身份服务器 4 + AspNetCore.Identity:X 尝试后如何锁定? - identity server 4 + AspNetCore.Identity: how to lockout after X tries? AspNetCore.Identity 不适用于自定义用户/角色实现 - AspNetCore.Identity not working with custom User/Role implementation AspNetCore.Identity UserManager CreateAsync无法保存关系 - AspNetCore.Identity UserManager CreateAsync cannot save relationships AspNetCore.Identity重置密码-无法跟踪“ X”的实例 - AspNetCore.Identity Reset Password - Instance of 'X' cannot be tracked
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM