首页 文章

在MVC中使用ASP.NET Identity和我自己的实体

提问于
浏览
2

在我的“租车”解决方案中,我有一个单独的项目,包含我的所有实体,如用户,角色,汽车,预订等 . 我使用EntityFramework Code First来生成数据库 . 所有这一切都很好 . 我在我的解决方案中添加了一个MVC项目 . 现在我想充分利用ASP.NET Identity 2.x模型 . 我的问题是:如何将MVC项目附带的ApplicationUser与我自己的用户类合并?我的用户类:

public partial class User
{
    public User()
    {
    }
    [Key]
    public int Id { get; set; }
    [StringLength(200)]
    public string FirstName { get; set; }
    [StringLength(200)]
    public string LastName { get; set; }
    [StringLength(200)]
    public string Address1 { get; set; }
    [StringLength(200)]
    public string Address2 { get; set; }
    [StringLength(200)]
    public string Address3 { get; set; }
    [StringLength(20)]
    public string ZipCode { get; set; }
    [StringLength(200)]
    public string City { get; set; }
    [StringLength(200)]
    public string Country { get; set; }
    [StringLength(200)]
    public string Phone { get; set; }
    [StringLength(200)]
    public string MobilePhone { get; set; }
    [StringLength(200)]
    public string WorkPhone { get; set; }
}

我应该将所有User属性移动到ApplicationUser类,并在我自己的类(例如Booking类)中向ApplicationUser添加外键吗?

3 回答

  • 1

    ApplicationUser 没什么特别的 . 它只是继承自 IdentityUser 的类的默认实现 . 即便如此,该继承仅仅是为了引导身份中的所有功能,例如角色,声明等 .

    您可以完全删除 ApplicationUser 并使您的用户类继承自 IdentityUser ,也可以将属性从您的用户类移至 ApplicationUser 并删除您的用户类 . 无论哪种方式,结果都是一样的 .

    并且,是的,您希望在与"user"相关的类之间创建外键,并且任何类最终都是您的"user"类 . 同样, ApplicationUser 并没有什么特别之处,所以如果您选择坚持使用它,您可以像项目中的任何其他POCO一样设置它,根据需要与其他实体 Build 关系 .

    有些人建议从 ApplicationUser 继承您的用户类,但我不是一个好主意 . 有正当理由从用于身份的基础"user"类继承,但是在这里你're not dealing with different types of users, but rather one user type that needs additional properties. Inheritance is really only an acceptable way to achieve that if you have no access to the base class to modify it. Here, you do. It'是你的类;项目模板只是为您创建的 .

  • 0

    这将是所有用户的基类

    public abstract class User : IdentityUser
    {
        public abstract string Area { get; }
        public bool IsActiveDirectoryUser { get; private set; }
    
        protected User(string username, bool isActiveDirectoryUser = false)
            : base(username)
        {
            IsActiveDirectoryUser = isActiveDirectoryUser;
        }
    
        protected User()
        { }
    }
    

    这是用户的一个例子

    public class AdminUser : User
    {
        public AdminUser(string username, bool isActiveDirectoryUser = false)
            : base(username, isActiveDirectoryUser)
        { }
    
        private AdminUser()
        { }
    
        public override string Area
        {
            get { return UserAreas.Admin; }
        }
    }
    

    这是DBContext,忽略用户的映射是属性,因为它是硬编码的

    public class IdentityDataContext : IdentityDbContext<User>
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Entity<User>().ToTable("AspNetUsers").Ignore(u => u.Area);
            modelBuilder.Entity<AdminUser>().ToTable("AdminUsers");
        }
    }
    

    这是您对IUserManager的自定义实现 . 它适用于实体User,使用我们已定义的IdentityDataContext和我们的自定义ClaimsFactory,如果有必要,如下所示

    public class UserManager
    {
        private readonly UserManager<User> _identityManager;
    
        public UserManager(ClaimsFactory claimsFactory, IdentityDataContext context, IdentityValidator identityValidator)
        {
            _identityManager = new UserManager<User>(new UserStore<User>(context))
                               {
                                   ClaimsIdentityFactory = claimsFactory,
                                   UserValidator = identityValidator
                               };
        }
    
        public void Register(User user, string password)
        {
            var result = _identityManager.Create(user, password);
    
            if (!result.Succeeded)
                throw new ApplicationException("User can not be created. " + result.Errors.FirstOrDefault());
        }
    
        public void Register(User user)
        {
            var result = _identityManager.Create(user);
    
            if (!result.Succeeded)
                throw new ApplicationException("User can not be created. " + result.Errors.FirstOrDefault());
        }
        public User Find(string userName, string password)
        {
            return _identityManager.Find(userName, password);
        }
    
        public ClaimsIdentity CreateIdentity(User user, string applicationCookie)
        {
            return _identityManager.CreateIdentity(user, applicationCookie);
        }
    
        public User FindByUserName(string userName)
        {
            return _identityManager.FindByName(userName);
        }
    
        public bool ChangePassword(string identifier, string oldPassword, string newPassword)
        {
            return _identityManager.ChangePassword(identifier, oldPassword, newPassword).Succeeded;
        }
    
        public bool ResetPassword(string userName, string password)
        {
            try
            {
                var user = FindByUserName(userName);
    
                var result = _identityManager.RemovePassword(user.Id);
    
                if (result != IdentityResult.Success)
                    return false;
    
                result = _identityManager.AddPassword(user.Id, password);
    
                return result == IdentityResult.Success;
            }
            catch (Exception)
            {
                return false;
            }
        }
    
        public User FindById(string userId)
        {
            return _identityManager.FindById(userId);
        }
    
        public bool IsInRole(string userId, string role)
        {
            return _identityManager.IsInRole(userId, role);
        }
    
        public void AddToRole(string userId, string role)
        {
            _identityManager.AddToRole(userId, role);
        }
    }
    

    如果您想索赔,这是索赔工厂 . 它将de user区域转换为声明,最后是浏览器中的cookie .

    public class ClaimsFactory : ClaimsIdentityFactory<User>
    {
        public async override Task<ClaimsIdentity> CreateAsync(UserManager<User> manager, User user, string authenticationType)
        {
            var identity = await base.CreateAsync(manager, user, authenticationType);
    
            identity.AddClaim(new Claim(ClaimTypes.Area, user.Area, ClaimValueTypes.String));
    
            return identity;
        }
    }
    
  • 2

    但是,嘿,您是否只能从ApplicationUser链接到您的用户模型?

    有时移动这样的代码并不容易 . 如果是这样的话,你可以这样做:

    public class ApplicationUser {
          public virtual YourUserModel userModel { get; set; }
    }
    

    希望能帮助到你!

    EDIT: 或者,您可以像Callum所说的那样,让您的User类继承自IdentityUser:

    public class User : IdentityUser {
         //your properties here
    }
    

相关问题