我的设置
目前,我有两个继承自 ApplicationUser
的模型, 它继承了 IdentityUser
.用户类是:
public abstract class ApplicationUser : IdentityUser
{
[PersonalData]
public string FirstName { get; set; }
[PersonalData]
public string LastName { get; set; }
[NotMapped]
public string FullName => $"{FirstName} {LastName}";
}
public class StudentUser : ApplicationUser
{
[PersonalData]
[Required]
public string StudentNumber { get; set; }
// A user belongs to one group
public Group Group { get; set; }
}
public class EmployeeUser : ApplicationUser { }
ApplicationUser
包含共享 属性,例如名字和姓氏。两者 StudentUser
和 EmployeeUser
有他们自己的属性和关系。此结构遵循 Table Per Hierarchy (TPH)遗产。
理想情况下,我想关注 Table Per Type (TPT)继承,因为SQL结构更好。 ASP.NET Core 仅原生支持 TPH,所以这就是我遵循 TPT 方法的原因。
问题
我在 Startup.cs
中添加了身份服务:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
当我调用 UserManager<StudentUser>
或 UserManager<EmployeeUser>
,我收到以下错误:
No service for type 'Microsoft.AspNetCore.Identity.UserManager`1[ClassroomMonitor.Models.StudentUser]' has been registered.
我的问题
不幸的是,我找不到太多关于此错误与此实现相结合的信息。
是否(甚至)可以让它以这种方式工作?
欢迎任何帮助或想法。
更新 1
手动添加 StudentUser
或 EmployeeUser
因为范围内的服务似乎不起作用(作为第一个提到 answer )。
services.AddScoped<UserManager<ApplicationUser>, UserManager<ApplicationUser>>();
// or..
services.AddScoped<UserManager<ApplicationUser>>();
这会引发以下错误:
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[ClassroomMonitor.Models.StudentUser]'
更新 2
这是一个Gist让您更好地了解项目结构:
最佳答案
理想情况下,您将为派生用户类型调用与基本用户类型相同的身份设置。
不幸的是 AddIdentity
方法包含一些防止多次使用它的代码。
相反,您可以使用 AddIdentityCore
.角色服务已由 AddIdentity
注册, 唯一的区别是 AddIdentityCore
寄存器 UserClaimsPrincipalFactory<TUser>
, 所以为了匹配 AddIdentity
setup 它需要替换为 UserClaimsPrincipalFactory<TUser, TRole>
通过 AddClaimsPrincipalFactory
方法。
代码看起来像这样:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddDefaultUI();
services.AddIdentityCore<StudentUser>()
.AddRoles<IdentityRole>()
.AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<StudentUser, IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddDefaultUI();
services.AddIdentityCore<EmployeeUser>()
.AddRoles<IdentityRole>()
.AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<EmployeeUser, IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddDefaultUI();
当然,您可以在自定义扩展方法中移动公共(public)部分。
更新:虽然角色服务已经配置好了,但是还是需要调用AddRoles
为了正确设置 Role
IndentityBuilder
的属性(property),然后由 AddEntityFrameworkStores
使用.
关于c# - 使用多个身份用户时没有类型 Identity.UserManager 的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52697550/