在 Identity Asp.net core 3 MVC 中创建服务 IUserStore 时出错
Error in Service IUserStore being created in Identity Asp.net core 3 MVC
更新
请参阅下面的更新。
我问了一个previous Whosebug question very recently, but I face an issue after implementing the suggested solutions from the following 2 places Identity model customization in ASP.NET Core and Custom storage providers for ASP.NET Core Identity。我只是无法使解决方案起作用。我已经按照建议实现了 IdentityUser
的扩展和 IdentityRole
的扩展。我已经为 UserStore
实现了 IUserPasswordStore
和 IUserRoleStore
以及 IUserStore
,并且我已经为 RoleStore
实现了 IRoleStore
。我还实现了新的 dbContext ApplicationDbContext
,它实现了 IdentityDbContext
。构造函数不接受参数存在一个问题,所以我实现了一个新的构造函数。我不确定这是否正确。
但这似乎无关紧要,因为我在调用
时在 Program.cs 的 Main 方法中遇到错误
CreateHostBuilder(args).Build().Run();
而且错误很大。我把它放在最后了。在线搜索错误部分并没有提供关于我在做什么的任何想法,而且由于我是 ASP.NET Core 3 和 Identity 的新手,我很困惑。
这是我目前的代码。
ConfigureServices 方法
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(policy));
options.EnableEndpointRouting = false;
});
services.AddDbContext<EntitiesModel>(options => options.UseSqlServer(
Configuration["Data:ConnectionStrings:XXXXDbConnection"]));
services.AddIdentity<UserViewModel,RoleViewModel>().AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders().AddRoles<RoleViewModel>(); ;
services.AddTransient<IUserStore<UserViewModel>, UserStore>();
services.AddTransient<IRoleStore<RoleViewModel>, RoleStore>();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Login";
options.LogoutPath = "/Logout";
});
}
ApplicationDbContext - 这些都在同一个命名空间中
public class IdentityDbContext
: IdentityDbContext<IdentityUser, IdentityRole, string>
{
public IdentityDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
public class IdentityDbContext<TUser>
: IdentityDbContext<TUser, IdentityRole, string>
where TUser : IdentityUser
{
public IdentityDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
// Uses the built-in Identity types except with custom User and Role types
// The key type is defined by TKey
public class IdentityDbContext<TUser, TRole, TKey> : IdentityDbContext<
TUser, TRole, TKey, IdentityUserClaim<TKey>, IdentityUserRole<TKey>,
IdentityUserLogin<TKey>, IdentityRoleClaim<TKey>, IdentityUserToken<TKey>>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
{
private DbContextOptions<ApplicationDbContext> options;
//private string nameOrConnectionString;
public IdentityDbContext(DbContextOptions<ApplicationDbContext> options)
{
this.options = options;
}
}
public abstract class IdentityDbContext<
TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
: IdentityUserContext<TUser, TKey>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserRole : IdentityUserRole<TKey>
{
}
public class ApplicationDbContext : IdentityDbContext<UserViewModel,RoleViewModel,int>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<UserViewModel>(b =>
{
b.HasMany(e => e.UserRoles)
.WithOne()
.HasForeignKey(ur => ur.Id)
.IsRequired();
});
modelBuilder.Entity<UserViewModel>(b =>
{
b.ToTable("T_CustomerContacts");
});
modelBuilder.Entity<RoleViewModel>(b =>
{
b.ToTable("T_LoginRoles");
});
modelBuilder.Entity<UserRoleViewModel>(b =>
{
b.ToTable("T_CustomerContactRole");
});
modelBuilder.Entity<RoleViewModel>(b =>
{
b.HasMany(e => e.UserRoles)
.WithOne(e => e.Role)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
});
}
}
UserViewModel
public class UserViewModel : IdentityUser<int>
{
UserRoleViewModel
public class UserRoleViewModel : IdentityUserRole<int>
{
RoleViewModel
public class RoleViewModel : IdentityRole<int>
{
角色库
public class RoleStore : IRoleStore<RoleViewModel>
{
用户商店
public class UserStore : IUserStore<UserViewModel>, IUserPasswordStore<UserViewModel>, IUserRoleStore<UserRoleViewModel>
{
我必须补充一点,这是我尝试过的最终配置。我尝试了很多组合和解决方案。
部分错误如下
An error occurred while starting the application.
AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserStore1[TrussCorp.CustomerPortal.Models.ViewModel.Identity.UserViewModel] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore
4[TrussCorp.CustomerPortal.Models.ViewModel.Identity.UserViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]': Unable to resolve service for type 'TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore4[TrussCorp.CustomerPortal.Models.ViewModel.Identity.UserViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IRoleStore
1[TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore3[TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]': Unable to resolve service for type 'TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore
3[TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]'.)
Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors, ServiceProviderOptions options)
更新
我回到了上一个问题的起点,但通过颠倒以下顺序解决了上述错误
services.AddTransient<IUserStore<UserViewModel>, UserStore>();
services.AddTransient<IRoleStore<RoleViewModel>, TrussCorp.CustomerPortal.Identity.RoleStore>();
services.AddIdentity<UserViewModel,RoleViewModel>().AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders().AddRoles<RoleViewModel>();
但正如我现在所说的那样,我遇到了 Store does not implement IUserRoleStore UserManager.GetUserRoleStore() 错误,这让我回到了原点。
你能不能试着把这个添加到顶部?
services.AddIdentity<UserViewModel,RoleViewModel>().AddUserStore<UserStore>().AddRoleStore<RoleStore>();
我对其他开发人员的建议是,如果您在互联网上找不到类似的问题,那您就是在做一些愚蠢而独特的事情。
解决方案是改变这个
public class UserStore : IUserStore<UserViewModel>, IUserPasswordStore<UserViewModel>, IUserRoleStore<UserRoleViewModel>
{
到这个
public class UserStore : IUserStore<UserViewModel>, IUserPasswordStore<UserViewModel>, IUserRoleStore<UserViewModel>
{
更新
请参阅下面的更新。
我问了一个previous Whosebug question very recently, but I face an issue after implementing the suggested solutions from the following 2 places Identity model customization in ASP.NET Core and Custom storage providers for ASP.NET Core Identity。我只是无法使解决方案起作用。我已经按照建议实现了 IdentityUser
的扩展和 IdentityRole
的扩展。我已经为 UserStore
实现了 IUserPasswordStore
和 IUserRoleStore
以及 IUserStore
,并且我已经为 RoleStore
实现了 IRoleStore
。我还实现了新的 dbContext ApplicationDbContext
,它实现了 IdentityDbContext
。构造函数不接受参数存在一个问题,所以我实现了一个新的构造函数。我不确定这是否正确。
但这似乎无关紧要,因为我在调用
时在 Program.cs 的 Main 方法中遇到错误CreateHostBuilder(args).Build().Run();
而且错误很大。我把它放在最后了。在线搜索错误部分并没有提供关于我在做什么的任何想法,而且由于我是 ASP.NET Core 3 和 Identity 的新手,我很困惑。
这是我目前的代码。
ConfigureServices 方法
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(policy));
options.EnableEndpointRouting = false;
});
services.AddDbContext<EntitiesModel>(options => options.UseSqlServer(
Configuration["Data:ConnectionStrings:XXXXDbConnection"]));
services.AddIdentity<UserViewModel,RoleViewModel>().AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders().AddRoles<RoleViewModel>(); ;
services.AddTransient<IUserStore<UserViewModel>, UserStore>();
services.AddTransient<IRoleStore<RoleViewModel>, RoleStore>();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Login";
options.LogoutPath = "/Logout";
});
}
ApplicationDbContext - 这些都在同一个命名空间中
public class IdentityDbContext
: IdentityDbContext<IdentityUser, IdentityRole, string>
{
public IdentityDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
public class IdentityDbContext<TUser>
: IdentityDbContext<TUser, IdentityRole, string>
where TUser : IdentityUser
{
public IdentityDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
}
// Uses the built-in Identity types except with custom User and Role types
// The key type is defined by TKey
public class IdentityDbContext<TUser, TRole, TKey> : IdentityDbContext<
TUser, TRole, TKey, IdentityUserClaim<TKey>, IdentityUserRole<TKey>,
IdentityUserLogin<TKey>, IdentityRoleClaim<TKey>, IdentityUserToken<TKey>>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
{
private DbContextOptions<ApplicationDbContext> options;
//private string nameOrConnectionString;
public IdentityDbContext(DbContextOptions<ApplicationDbContext> options)
{
this.options = options;
}
}
public abstract class IdentityDbContext<
TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
: IdentityUserContext<TUser, TKey>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserRole : IdentityUserRole<TKey>
{
}
public class ApplicationDbContext : IdentityDbContext<UserViewModel,RoleViewModel,int>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<UserViewModel>(b =>
{
b.HasMany(e => e.UserRoles)
.WithOne()
.HasForeignKey(ur => ur.Id)
.IsRequired();
});
modelBuilder.Entity<UserViewModel>(b =>
{
b.ToTable("T_CustomerContacts");
});
modelBuilder.Entity<RoleViewModel>(b =>
{
b.ToTable("T_LoginRoles");
});
modelBuilder.Entity<UserRoleViewModel>(b =>
{
b.ToTable("T_CustomerContactRole");
});
modelBuilder.Entity<RoleViewModel>(b =>
{
b.HasMany(e => e.UserRoles)
.WithOne(e => e.Role)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
});
}
}
UserViewModel
public class UserViewModel : IdentityUser<int>
{
UserRoleViewModel
public class UserRoleViewModel : IdentityUserRole<int>
{
RoleViewModel
public class RoleViewModel : IdentityRole<int>
{
角色库
public class RoleStore : IRoleStore<RoleViewModel>
{
用户商店
public class UserStore : IUserStore<UserViewModel>, IUserPasswordStore<UserViewModel>, IUserRoleStore<UserRoleViewModel>
{
我必须补充一点,这是我尝试过的最终配置。我尝试了很多组合和解决方案。 部分错误如下
An error occurred while starting the application. AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserStore
1[TrussCorp.CustomerPortal.Models.ViewModel.Identity.UserViewModel] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore
4[TrussCorp.CustomerPortal.Models.ViewModel.Identity.UserViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]': Unable to resolve service for type 'TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore4[TrussCorp.CustomerPortal.Models.ViewModel.Identity.UserViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IRoleStore
1[TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore3[TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]': Unable to resolve service for type 'TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore
3[TrussCorp.CustomerPortal.Models.ViewModel.Identity.RoleViewModel,TrussCorp.CustomerPortal.Models.ViewModel.Identity.ApplicationDbContext,System.Int32]'.) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors, ServiceProviderOptions options)
更新
我回到了上一个问题的起点,但通过颠倒以下顺序解决了上述错误
services.AddTransient<IUserStore<UserViewModel>, UserStore>();
services.AddTransient<IRoleStore<RoleViewModel>, TrussCorp.CustomerPortal.Identity.RoleStore>();
services.AddIdentity<UserViewModel,RoleViewModel>().AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders().AddRoles<RoleViewModel>();
但正如我现在所说的那样,我遇到了 Store does not implement IUserRoleStore UserManager.GetUserRoleStore() 错误,这让我回到了原点。
你能不能试着把这个添加到顶部?
services.AddIdentity<UserViewModel,RoleViewModel>().AddUserStore<UserStore>().AddRoleStore<RoleStore>();
我对其他开发人员的建议是,如果您在互联网上找不到类似的问题,那您就是在做一些愚蠢而独特的事情。
解决方案是改变这个
public class UserStore : IUserStore<UserViewModel>, IUserPasswordStore<UserViewModel>, IUserRoleStore<UserRoleViewModel>
{
到这个
public class UserStore : IUserStore<UserViewModel>, IUserPasswordStore<UserViewModel>, IUserRoleStore<UserViewModel>
{