我有 asp.net 核心 webapi 应用程序,它当前在类中使用Microsoft.AspNetCore.Identity
和方法,到目前为止一切正常。services.AddDbContext
ConfigureServices
Startup
我尝试使用services.AddPooledDbContextFactory
而不是services.AddDbContext
提高性能。但是,当我尝试使用时AddPooledDbContextFactory
出现错误:
System.InvalidOperationException:尝试激活“Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore
5[hostapp.Models.AppRole,hostapp.Data.DataContext,System.Int32,hostapp.Models.AppUserRole,Microsoft.AspNetCore.Identity.IdentityRoleClaim
1[System.Int32]]”时无法解析“hostapp.Data.DataContext”类型的服务
看到这个错误后,我创建了新的 webapi 项目,AddPooledDbContextFactory
没有Microsoft.AspNetCore.Identity
它可以正常工作。所以我的问题是:
services.AddPooledDbContextFactory
使用withMicrosoft.AspNetCore.Identity
来避免上述错误的正确方法是什么?
在ProjectRoot/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();
});
}
}
}
在ProjectRoot/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();
}
}
}
在ProjectRoot/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>