为什么我收到IdentityRole错误?

Sea*_*ome 3 asp.net-mvc entity-framework entity-framework-5 asp.net-identity asp.net-mvc-5.1

使用Identity 2.0注册用户后,在数据库中创建用户,Account控制器中有代码创建身份并在用户签名.这是我收到错误的时候.以下是产生错误的代码:

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
Run Code Online (Sandbox Code Playgroud)

这是错误:

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

我的模型看起来像这样:

namespace MyApp.Models
{
    public class ApplicationUser : IdentityUser
    {
        [Required]
        [StringLength(50)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(50)]
        public string LastName { get; set; }
    }

    public class ApplicationRole : IdentityRole
    {
        [Required]
        [StringLength(50)]
        public string ProperName { get; set; }

        [Required]
        public string Description { get; set; }
    }


    public class MyAppDb : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
    {
        public MyAppDb()
            : base("MyAppDb")
        {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

UserManager是在帐户控制器中这样创建的:

namespace MyApp.Controllers
{
    [Authorize]
    public class AccountController : BaseController
    {
        private UserManager<ApplicationUser> _userManager;

        public AccountController()
        {
        }

        public AccountController(UserManager<ApplicationUser> userManager)
        {
            UserManager = userManager;
        }

        public UserManager<ApplicationUser> UserManager
        {
            get
            {
                return _userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyAppDb()));
            }
            private set
            {
                _userManager = value;
            }
        }

        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

Sea*_*ome 5

我花了很多时间在这个问题上并发布了许多问题来深入了解它.我当然希望这些信息有助于其他人.

基本上,定制User很容易,有几个例子可用.然而,定制Role是有问题的,我发现的唯一例子远远超出"开箱即用"的范围,我能够在解决Id问题后得到一个工作.那个案子的问题是我必须自己创造Id.这是一个问题:UserManager.Create(用户,密码)是否存在EntityValidationError,表示Id是必需的?

所以在简单的例子中,注意当你只是自定义User你的DbContext继承IdentityDbContext而你只是提供IdentityUser,在我的情况下它被调用ApplicationUser,看起来像这样IdentityDbContext<ApplicationUser>.另请注意,UserManager并且UserStore也提供了IdentityUser,并且在大多数示例中看起来像这样new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))

但是,一旦你自定义Role你需要传递的一切,包括密钥类型TKey的的Id领域.我看起来像这样,IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>因为我只定制了UserRole.

但你还没有完成,因为常规UserManager不再理解.我认为这是身份伙伴可以/应该修复的东西,但我离题了.所以我必须实现自己的UserStoreUserManager注意(这是让我绊倒的部分)你必须在KType这里提供或者实例化你的自定义UserManager会给你一个编译时错误:

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
    public ApplicationUserStore(MyAppDb context)
        : base(context)
    {
    }
}

public class ApplicationUserManager : UserManager<ApplicationUser, string>
{
    public ApplicationUserManager(IUserStore<ApplicationUser, string> store)
        : base(store)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

UserManager在帐户控制器中实例化如下new ApplicationUserManager(new ApplicationUserStore(new MyAppDb())):

public class AccountController : BaseController
{
    private ApplicationUserManager _userManager;

    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager)
    {
        UserManager = userManager;
    }

    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager = new ApplicationUserManager(new ApplicationUserStore(new MyAppDb()));
        }
        private set
        {
            _userManager = value;
        }
    }

    ...

}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!