System.InvalidOperationException:方案已存在:Identity.Application:身份脚手架之后
System.InvalidOperationException: Scheme already exists: Identity.Application: After Identity Scaffolding
我有一个现有的ApplicationUser
,我想修改登录的UI页面。所以这就是我决定进行脚手架操作的原因。
ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
public List<Student> Students { get; set; }
}
但是当我使用最后一个 CLI
命令时:
dotnet aspnet-codegenerator identity --files="Account.Login;"
我无法 运行 我的网络应用程序,这是它在网络上显示的内容:
然后,这是日志中出现的错误:
Unhandled Exception: System.InvalidOperationException: Scheme already
exists: Identity.Application at
Microsoft.AspNetCore.Authentication.AuthenticationOptions.AddScheme(String
name, Action1 configureBuilder) at
Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0
2.b__0(AuthenticationOptions
o) at
Microsoft.Extensions.Options.ConfigureNamedOptions1.Configure(String
name, TOptions options) at
Microsoft.Extensions.Options.OptionsFactory
1.Create(String name)
at
Microsoft.Extensions.Options.OptionsManager1.<>c__DisplayClass5_0.<Get>b__0()
at System.Lazy
1.ViaFactory(LazyThreadSafetyMode mode) at
System.Lazy1.ExecutionAndPublication(LazyHelper
executionAndPublication, Boolean useDefaultConstructor) at
System.Lazy
1.CreateValue() at
Microsoft.Extensions.Options.OptionsCache1.GetOrAdd(String name,
Func
1 createOptions) at
Microsoft.Extensions.Options.OptionsManager1.Get(String name) at
Microsoft.Extensions.Options.OptionsManager
1.get_Value() at
Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions1
options, IDictionary
2 schemes) at
Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions1
options)
--- End of stack trace from previous location where exception was thrown --- at
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite
constructorCallSite, ServiceProviderEngineScope scope) at
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSite
callSite, TArgument argument) at
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite
scopedCallSite, ServiceProviderEngineScope scope) at
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite
singletonCallSite, ServiceProviderEngineScope scope) at
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite
callSite, TArgument argument) at
Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.b__0(ServiceProviderEngineScope
scope) at
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type
serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type
serviceType) at
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type
serviceType) at
Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider
provider) at
Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider
provider, Type instanceType, Object[] parameters) at
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.b__0(RequestDelegate
next) at
Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build() at
Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication() at
Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken
cancellationToken) at
Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host,
CancellationToken token, String shutdownMessage) at
Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host,
CancellationToken token) at
Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
at ICFERApp.Program.Main(String[] args) in
/Users/idrislutaaya/RiderProjects/ICFERApp/ICFERApp/Program.cs:line 17
我看过这个 但它对我没有帮助。
实际上让我感到惊讶的是,有一个 DBClass 在下面的目录 ~/Areas/Identity/Data 中创建了它自己:
public class ICFERAppIdentityDbContext : IdentityDbContext<IdentityUser>
{
public ICFERAppIdentityDbContext(DbContextOptions<ICFERAppIdentityDbContext> 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 class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<ApplicationUser>()
.HasMany(s => s.Students)
.WithOne(u => u.User);
builder.Entity<Student>()
.HasOne(e => e.Education)
.WithOne(s => s.Student);
builder.Entity<Student>()
.HasOne(g => g.Guardian)
.WithOne(s => s.Student);
builder.Entity<Student>()
.HasOne(p => p.Parents)
.WithOne(s => s.Student);
builder.Entity<Student>()
.HasOne(s => s.Siblings)
.WithOne(s => s.Student);
builder.Entity<Siblings>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Siblings>()
.HasKey(x => new { x.Id, x.StudentId});
builder.Entity<Education>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Education>()
.HasKey(x => new { x.Id, x.StudentId});
builder.Entity<Guardian>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Guardian>()
.HasKey(x => new { x.Id, x.StudentId});
builder.Entity<Parents>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Parents>()
.HasKey(x => new { x.Id, x.StudentId});
}
}
然后,在我的 Startup.cs
文件中,我遵循了 Microsoft doc 所说的内容:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(
Configuration.GetConnectionString("DefaultConnection")));
services.AddTransient<IStudentRepository, StudentRepository>();
services.AddMvc().AddNToastNotifyToastr();
services.AddJsReport(new LocalReporting()
.UseBinary(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? JsReportBinary.GetBinary()
: jsreport.Binary.OSX.JsReportBinary.GetBinary())
.AsUtility()
.Create());
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddRazorPagesOptions(options =>
{
options.AllowAreas = true;
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseNToastNotify();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Student}/{action=Index}/{id?}");
});
}
}
根据以上所有信息,我的实施到底出了什么问题?
检查 IdentityHostingStartup.cs
并在下面注释掉它是否退出:
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ICFERAppIdentityDbContext>();
总之只需要一个身份配置。 Here是相关讨论。
我有一个现有的ApplicationUser
,我想修改登录的UI页面。所以这就是我决定进行脚手架操作的原因。
ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
public List<Student> Students { get; set; }
}
但是当我使用最后一个 CLI
命令时:
dotnet aspnet-codegenerator identity --files="Account.Login;"
我无法 运行 我的网络应用程序,这是它在网络上显示的内容:
然后,这是日志中出现的错误:
Unhandled Exception: System.InvalidOperationException: Scheme already exists: Identity.Application at Microsoft.AspNetCore.Authentication.AuthenticationOptions.AddScheme(String name, Action
1 configureBuilder) at Microsoft.AspNetCore.Authentication.AuthenticationBuilder.<>c__DisplayClass4_0
2.b__0(AuthenticationOptions o) at Microsoft.Extensions.Options.ConfigureNamedOptions1.Configure(String name, TOptions options) at Microsoft.Extensions.Options.OptionsFactory
1.Create(String name)
at Microsoft.Extensions.Options.OptionsManager1.<>c__DisplayClass5_0.<Get>b__0() at System.Lazy
1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy
1.CreateValue() at Microsoft.Extensions.Options.OptionsCache1.GetOrAdd(String name, Func
1 createOptions) at Microsoft.Extensions.Options.OptionsManager1.Get(String name) at Microsoft.Extensions.Options.OptionsManager
1.get_Value() at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions1 options, IDictionary
2 schemes) at Microsoft.AspNetCore.Authentication.AuthenticationSchemeProvider..ctor(IOptions1 options) --- End of stack trace from previous location where exception was thrown --- at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor
2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitSingleton(SingletonCallSite singletonCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType) at Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider) at Microsoft.Extensions.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters) at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass4_0.b__0(RequestDelegate next) at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.Build() at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication() at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token) at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
at ICFERApp.Program.Main(String[] args) in /Users/idrislutaaya/RiderProjects/ICFERApp/ICFERApp/Program.cs:line 17
我看过这个
实际上让我感到惊讶的是,有一个 DBClass 在下面的目录 ~/Areas/Identity/Data 中创建了它自己:
public class ICFERAppIdentityDbContext : IdentityDbContext<IdentityUser>
{
public ICFERAppIdentityDbContext(DbContextOptions<ICFERAppIdentityDbContext> 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 class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<ApplicationUser>()
.HasMany(s => s.Students)
.WithOne(u => u.User);
builder.Entity<Student>()
.HasOne(e => e.Education)
.WithOne(s => s.Student);
builder.Entity<Student>()
.HasOne(g => g.Guardian)
.WithOne(s => s.Student);
builder.Entity<Student>()
.HasOne(p => p.Parents)
.WithOne(s => s.Student);
builder.Entity<Student>()
.HasOne(s => s.Siblings)
.WithOne(s => s.Student);
builder.Entity<Siblings>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Siblings>()
.HasKey(x => new { x.Id, x.StudentId});
builder.Entity<Education>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Education>()
.HasKey(x => new { x.Id, x.StudentId});
builder.Entity<Guardian>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Guardian>()
.HasKey(x => new { x.Id, x.StudentId});
builder.Entity<Parents>()
.Property(p => p.Id)
.ValueGeneratedOnAdd();
builder.Entity<Parents>()
.HasKey(x => new { x.Id, x.StudentId});
}
}
然后,在我的 Startup.cs
文件中,我遵循了 Microsoft doc 所说的内容:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(
Configuration.GetConnectionString("DefaultConnection")));
services.AddTransient<IStudentRepository, StudentRepository>();
services.AddMvc().AddNToastNotifyToastr();
services.AddJsReport(new LocalReporting()
.UseBinary(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? JsReportBinary.GetBinary()
: jsreport.Binary.OSX.JsReportBinary.GetBinary())
.AsUtility()
.Create());
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddRazorPagesOptions(options =>
{
options.AllowAreas = true;
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseNToastNotify();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Student}/{action=Index}/{id?}");
});
}
}
根据以上所有信息,我的实施到底出了什么问题?
检查 IdentityHostingStartup.cs
并在下面注释掉它是否退出:
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ICFERAppIdentityDbContext>();
总之只需要一个身份配置。 Here是相关讨论。