代码之家  ›  专栏  ›  技术社区  ›  Matthijs shashishailaj

没有类型为“Microsoft.AspNetCore.Identity.UserManager”的服务`StudentUser

  •  12
  • Matthijs shashishailaj  · 技术社区  · 6 年前

    我的设置

    目前,我有两个模型继承自 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 { }
    

    这个 应用程序用户 共享 StudentUser EmployeeUser 有他们的 属性和关系。这种结构遵循 Table Per Hierarchy (TPH) 继承权。

    理想情况下,我想遵循 Table Per Type (TPT) 继承,因为SQL结构更好。ASP.NET内核只在本机支持TPH,所以我采用TPT方法。

    我在中添加了身份服务 Startup.cs :

    services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
    

    当我打电话的时候 UserManager<StudentUser> UserManager<EmployeeUser> ,我得到以下错误:

    尚未注册类型为“Microsoft.AspNetCore.Identity.UserManager`1[ClassroomMonitor.Models.StudentUser]”的服务。

    我的问题

    不幸的是,结合这个实现,我找不到太多关于这个错误的信息。

    这样做(甚至)可能吗?

    欢迎任何帮助或想法。

    学生用户 雇员用户 作为一个作用域服务似乎不起作用(作为第一个 answer ).

    services.AddScoped<UserManager<ApplicationUser>, UserManager<ApplicationUser>>();
    // or..
    services.AddScoped<UserManager<ApplicationUser>>();
    

    这将引发以下错误:

    更新2

    这是一个 Gist

    4 回复  |  直到 5 年前
        1
  •  12
  •   Ivan Stoev    6 年前

    理想情况下,您可以为派生用户类型调用与基本用户类型相同的标识设置。

    不幸的是 AddIdentity 方法包含一些防止多次使用它的代码。

    相反,你可以用 AddIdentityCore . 角色服务已由注册 额外性 ,唯一的区别是 附加矿 UserClaimsPrincipalFactory<TUser> ,所以为了匹配 额外性 安装程序需要替换为 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();
    

    当然,您可以在自定义扩展方法中移动公共部分。

    更新: 虽然已经配置了角色服务,但是仍然需要调用 AddRoles 为了正确设置 Role IndentityBuilder ,然后由 AddEntityFrameworkStores

        2
  •  0
  •   Nguyễn Thái Hải    6 年前

    你错过了它。

    services.AddScoped<UserManager<AppUser>, UserManager<AppUser>>()
    

    StudentUser和EmployeeUser与之类似

        3
  •  0
  •   UbuntuCore    6 年前

    在fresh项目上测试:

    dotnet新mvc——身份验证个人

    启动.cshtml

    services.AddDefaultIdentity<User>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
    

    public class User : IdentityUser
    {
        public string Test { get; set; }
    }
    

    可能你的问题是:

    _登录.cshtml

    @inject SignInManager<User> SignInManager
    @inject UserManager<User> UserManager
    

    启动.cs

    services.AddDefaultIdentity<User2>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
    

    public class User : IdentityUser
    {
        public string TestA { get; set; }
    }
    public class User2 : User
    {
        public string TestB { get; set; }
    }
    

    _登录.cshtml

    @inject SignInManager<User2> SignInManager
    @inject UserManager<User2> UserManager
    
        4
  •  0
  •   Kyle B Cox    6 年前

    你应该真正地组织你的数据,让它有一个 ApplicationUser 由雇员实体(单独的实体)或学生实体(同样是单独的实体)引用。 这里更多的是设计问题,而不是代码问题。

    ASPIdentity将注入 Usermanager<ApplicationUser> 当你 AddIdentity<ApplicationUser, IdentityRole> ,因此添加更多的用户管理器将无法按预期工作。

    答案

    那么当你 addIdentity 你可以注册 (目前的情况)然后注入 UserManager<ApplicationUser>

        5
  •  0
  •   tayfun KılÄ±ç    4 年前

    如果核心>=3

    services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<WorldContext>();