在我的"租车"解决方案我有一个单独的项目,包含我的所有实体,如用户,角色,汽车,预订等。我使用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; }
}
我应该将所有用户属性移动到ApplicationUser类,并在我自己的类(例如Booking类)中向ApplicationUser添加外键吗?
答案 0 :(得分:2)
ApplicationUser
没有什么特别之处。它只是继承自IdentityUser
的类的默认实现。即便如此,该继承仅仅是为了引导身份中的所有功能,例如角色,声明等。
您可以完全删除ApplicationUser
并使用户类继承自IdentityUser
,也可以将属性从用户类移至ApplicationUser
并删除您的用户类。无论哪种方式,结果都是一样的。
而且,是的,您希望在与" user"相关的类之间创建外键。无论什么课程最终成为你的用户"类。同样,ApplicationUser
没有什么特别之处,所以如果你选择坚持,你可以像项目中的任何其他POCO一样设置它,根据需要与其他实体建立关系。
有些人建议从ApplicationUser
继承您的用户类,但我不认为这是一个好主意。有充分的理由继承基地"用户"用于Identity的类,但在这里您不处理不同类型的用户,而是处理需要其他属性的一种用户类型。如果您无法访问基类来修改它,那么继承实际上只是一种可接受的方法。在这里,你这样做。这是你的班级;项目模板只是为你创建的。
答案 1 :(得分:1)
这将是所有用户的基类
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,如果是nesesary,如下所示
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 :(得分:0)
但是,嘿,您是否只能从ApplicationUser链接到您的用户模型?
有时移动这样的代码并不容易。如果是这样的话,你可以这样做:
public class ApplicationUser {
public virtual YourUserModel userModel { get; set; }
}
希望它有所帮助!
修改强> 或者,您可以像Callum所说的那样,让您的User类继承自IdentityUser:
public class User : IdentityUser {
//your properties here
}