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

时间:2015-05-20 13:49:37

标签: c# asp.net asp.net-mvc entity-framework 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; }
}

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

3 个答案:

答案 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
}