【问题标题】:The entity type IdentityRole is not part of the model for the current context after extending Roles table扩展 Roles 表后,实体类型 IdentityRole 不是当前上下文模型的一部分
【发布时间】:2019-01-29 19:35:29
【问题描述】:

我已经扩展了由 Entity Framework 创建的 AspNetRoles,如下所示:

public class AspNetRoles:IdentityRole
{
        public AspNetRoles() : base() { }
        public String Label { get; set; }
        public String ApplicationId { get; set; }
        public AspNetApplications Application { get; set; }

        public static readonly String SystemAdministrator = "SystemAdministrator";
}

我知道因为我扩展了身份角色表,所以我必须对我的用户管理器进行更改。这就是我所做的:

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = true;
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
        manager.MaxFailedAccessAttemptsBeforeLockout = 5;

        // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
        // You can write your own provider and plug it in here.
        manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is {0}"
        });
        manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });
        manager.EmailService = new EmailService();
        manager.SmsService = new SmsService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = 
                new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}

// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
        : base(userManager, authenticationManager)
    {
    }

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }

    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}

public class ApplicationRoleManager : RoleManager<AspNetRoles>, IDisposable
{
    public ApplicationRoleManager(RoleStore<AspNetRoles> store) : base(store)
    { }


    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        //AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
        //AppRoleManager manager = new AppRoleManager(new RoleStore<AppRole>(db));
        return new ApplicationRoleManager(new RoleStore<AspNetRoles>(context.Get<ApplicationDbContext>()));

        //return manager;
    }
}

public class ApplicationUserStore<TUser> : UserStore<TUser, AspNetRoles, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUserStore<TUser>, IUserStore<TUser, string>, IDisposable where TUser : IdentityUser
{
    public ApplicationUserStore(DbContext context) : base(context) { }
}

这是我的 DBContext:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, AspNetRoles, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
    {
        public virtual DbSet<AspNetUsersExtendedDetails> AspNetUsersExtendedDetails { get; set; }
        public virtual DbSet<AspNetApplications> AspNetApplications { get; set; }
        public virtual DbSet<AspNetEventLogs> AspNetEventLogs { get; set; }
        public ApplicationDbContext() : base("AppStudio")
        {

        }
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

但是,当我启动我的应用程序时出现此错误:

实体类型 IdentityRole 不是当前上下文模型的一部分。

我不确定为什么会这样。扩展角色表后,我是否遗漏了一些需要更改的内容?

【问题讨论】:

  • 不确定您使用的是 Code First 还是 Database First,但到目前为止,自定义角色需要修改 UserStore 和/或 UserManager(请参阅 herehere 以获得进一步说明)。
  • 嗨@TetsuyaYamamoto,我使用的是代码优先。我已经通过我所做的一些更改更新了我的问题。你能检查我是否遗漏了什么吗?
  • @TetsuyaYamamoto 我试图效仿你的例子,但没有改变。

标签: c# asp.net asp.net-mvc entity-framework


【解决方案1】:

简答

上述代码的主要问题在于UserManagerCreate 方法。在该方法中,您应该使用知道您创建的新角色类的UserStore 创建一个UserManager。为此,您可以使用您拥有的 ApplicationUserStore 类的实例或以这种方式创建新的用户存储:

new UserStore<ApplicationUser, [YourRoleClass], string, 
    IdentityUserLogin, IdentityUserRole, IdentityUserClaim(
        context.Get<ApplicationDbContext>())

如何向 IdentityRole 添加自定义属性?

要将新属性添加到IdentityRole,您可以按照以下步骤操作:

  1. 创建一个 ASP.NET Web 应用程序
  2. 确保选择 MVC 并且 AuthenticationIndividual User Accounts
  3. 转到 Models 文件夹 → 打开 IdentityModels.cs 并创建包含您要添加的自定义属性的 ApplicationRole 类:

    public class ApplicationRole : IdentityRole   //My custom role class
    {
        public string ApplicationId { get; set; } //My custom property
    }
    
  4. ApplicationUserGenerateUserIdentityAsync方法改为接受UserManager&lt;ApplicationUser, string&gt;类型的参数:

    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, string> manager)
        {
    
  5. 更改ApplicationDbContext基类并引入所有泛型参数:

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
    
  6. 构建项目。

  7. 转到 TOOLS 菜单 → Nuget 包管理器 → 单击 包管理器控制台
  8. 键入Enable-Migrations 并按Enter 并等待任务完成。
  9. 键入Add-Migration "ApplicationRole" 并按Enter 并等待任务完成。
  10. 输入Update-Database,然后按Enter,等待任务完成。
  11. 转到 App_Start 文件夹 → 打开 IdentityConfig.cs 并更改 ApplicationUserManager 类以派生自 UserManager&lt;ApplicationUser, string&gt; 并更改其 Create 方法以返回UserManage知道ApplicationRole

    public class ApplicationUserManager : UserManager<ApplicationUser, string>
    {
        public ApplicationUserManager(IUserStore<ApplicationUser, string> store)
            : base(store)
        {
        }
    
        public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
        {
            var manager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>(context.Get<ApplicationDbContext>()));
    
  12. 要管理角色,请在同一文件中创建ApplicationRoleManager 类:

    public class ApplicationRoleManager : RoleManager<ApplicationRole>
    {
        public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store) : base(store) { }
    
        public static ApplicationRoleManager Create(
            IdentityFactoryOptions<ApplicationRoleManager> options,
            IOwinContext context)
        {
            return new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
        }
    }
    
  13. 转到 App_Start 文件夹 → 打开 Startup.Auth.cs 并将以下代码添加到 ConfigureAuth 方法:

    ConfigureAuthapp.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
    

现在项目已准备好利用新的ApplicationRole

【讨论】:

  • 我会试试这个。太感谢了。目前,我刚刚在表中继承了带有鉴别器字段的 IdentityRole。似乎也可以正常工作?这个方法和我的有什么区别?
  • 不客气,主要区别在于第 11 步(和第 4 步)。
  • @El7or 不客气,感谢您的反馈。如果您还要自定义身份用户,您可能需要查看this post
  • @Örvar 太棒了!感谢您的反馈:)
猜你喜欢
  • 2017-01-11
  • 2017-06-01
  • 1970-01-01
  • 2014-04-04
  • 2015-03-22
  • 2013-11-10
  • 2014-11-30
  • 2017-06-19
  • 2011-06-26
相关资源
最近更新 更多