MVC 5自定义用户

时间:2013-11-13 18:22:44

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

所以我最近一直在玩MVC 5而且我喜欢它。 我遇到了一些我认为很容易做到的事情,但最终我吃了几个小时,而且我不是更聪明。

基本上我想通过添加自己的属性来扩展用户模型。我这样做了:

public class IdentityUser : User
{
    public IdentityUser()
    //: this(String.Empty)
    {
    }

    public IdentityUser(string userName)
        : base(userName)
    {
    }

    public string UserId { get; set; }
    public string CompanyId { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredTitle")]
    public string Title { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredFirstName")]
    public string Forename { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredLastName")]
    public string Surname { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredUserName")]
    public string UserName { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredEmail")]
    public string Email { get; set; }
    public string JobTitle { get; set; }
    public string Telephone { get; set; }
    public string Mobile { get; set; }
    public string Photo { get; set; }
    public string LinkedIn { get; set; }
    public string Twitter { get; set; }
    public string Facebook { get; set; }
    public string Google { get; set; }
    public string Bio { get; set; }

    public string CompanyName { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredCredentialId")]
    public string CredentialId { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredSecurityCode")]
    public string Code { get; set; }
    public bool IsLockedOut { get; set; }
    public bool IsApproved { get; set; }

    public DateTime LastLoginDate { get; set; }

    [Display(Name = "Can only edit own assets")]
    public bool UserCanEditOwn { get; set; }
    [Display(Name = "Can edit assets")]
    public bool UserCanEdit { get; set; }
    [Display(Name = "Can download assets")]
    public bool UserCanDownload { get; set; }
    [Display(Name = "Require approval to upload assets")]
    public bool UserRequiresApproval { get; set; }
    [Display(Name = "Can approve assets")]
    public bool UserCanApprove { get; set; }
    [Display(Name = "Can synchronise assets")]
    public bool UserCanSync { get; set; }

    public bool AgreedTerms { get; set; }
}

public class IdentityUserContext : IdentityStoreContext
{
    public IdentityUserContext(DbContext db)
        : base(db)
    {
        this.Users = new UserStore<IdentityUser>(this.DbContext);
    }
}

public class IdentityUserDbContext : IdentityDbContext<IdentityUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
}

用户是EF

中的默认用户类
namespace Microsoft.AspNet.Identity.EntityFramework
{
    public class User : IUser
    {
    public User();
    public User(string userName);

    [Key]
    public string Id { get; set; }
    public string UserName { get; set; }
    }
}

我继承了它,因为如果你想使用自定义类,我会读到你必须要做的事情。 无论如何,我然后将我的Register模型改为:

public class RegisterViewModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    public string Title { get; set; }
    [Required]
    public string Forename { get; set; }
    [Required]
    public string Surname { get; set; }
    [Required]
    public string Email { get; set; }

    public string CompanyName { get; set; }

    [Required]
    public string CredentialId { get; set; }
    [Required]
    public string Code { get; set; }
}

和看起来像这样的方法:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        try
        {
            // Create a profile, password, and link the local login before signing in the user
            var companyId = Guid.NewGuid().ToString();
            var user = new IdentityUser( model.UserName)
            {
                CompanyId = companyId,
                Title = model.Title,
                Forename = model.Forename,
                Surname = model.Surname,
                Email = model.Email,
                CompanyName = model.CompanyName,
                CredentialId = model.CredentialId
            };

            if (await IdentityStore.CreateLocalUser(user, model.Password))
            {
                await AuthenticationManager.SignIn(HttpContext, user.Id, isPersistent: false);
                return RedirectToAction("Setup", new { id = user.CompanyId });
            }
            else
            {
                ModelState.AddModelError("", "Failed to register user name: " + model.UserName);
            }
        }
        catch (IdentityException e)
        {
            ModelState.AddModelError("", e.Message);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

当我尝试注册时,我收到此错误:

Mapping and metadata information could not be found for EntityType 'TestProject.Models.IdentityUser'.

我无法弄清楚原因。

我错过了一步还是什么?

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:1)

您可以合并IdentityUser和User。只要它继承自IUser,你应该没问题。

也许从这开始。

编辑:

这是我正在使用的用户类,并使用EF Code First存储它。

public class User : IUser
{
    [Key]
    public string Id { get; set;}

    [Required]
    public UserType UserType { get; set; }

    [Required]
    [StringLength(255, MinimumLength = 5)]
    public string UserName { get; set; }
}

答案 1 :(得分:0)

添加演员怎么样?

IdentityStore.CreateLocalUser(user as User, model.Password)

答案 2 :(得分:0)

由于这篇文章,我想通了:

Custom Membership with Microsoft.AspNet.Identity - CreateLocalUser fails

我的班级现在看起来像这样:

public class User : IUser
{
    public User()
    {
        this.LastLoginDate = DateTime.UtcNow;
        this.DateCreated = DateTime.UtcNow;
    }

    public User(string userName)
    {
        this.Id = Guid.NewGuid().ToString();
        this.UserName = userName;

        this.CreatedBy = this.Id;

        this.LastLoginDate = DateTime.UtcNow;
        this.DateCreated = DateTime.UtcNow;

        this.IsApproved = true;
    }

    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredUserName")]
    public string UserName { get; set; }

    public string Id { get; set; }
    [Required] public string CompanyId { get; set; }

    [Required] public string CreatedBy { get; set; }
    public string ModifiedBy { get; set; }

    public DateTime DateCreated { get; set; }
    public DateTime? DateModified { get; set; }
    public DateTime LastLoginDate { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredTitle")]
    public string Title { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredFirstName")]
    public string Forename { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredLastName")]
    public string Surname { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredEmail")]
    public string Email { get; set; }
    public string JobTitle { get; set; }
    public string Telephone { get; set; }
    public string Mobile { get; set; }
    public string Photo { get; set; }
    public string LinkedIn { get; set; }
    public string Twitter { get; set; }
    public string Facebook { get; set; }
    public string Google { get; set; }
    public string Bio { get; set; }

    public string CompanyName { get; set; }

    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredCredentialId")]
    public string CredentialId { get; set; }
    [Required(ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "RequiredSecurityCode")]
    public bool IsLockedOut { get; set; }
    public bool IsApproved { get; set; }

    [Display(Name = "Can only edit own assets")]
    public bool CanEditOwn { get; set; }
    [Display(Name = "Can edit assets")]
    public bool CanEdit { get; set; }
    [Display(Name = "Can download assets")]
    public bool CanDownload { get; set; }
    [Display(Name = "Require approval to upload assets")]
    public bool RequiresApproval { get; set; }
    [Display(Name = "Can approve assets")]
    public bool CanApprove { get; set; }
    [Display(Name = "Can synchronise assets")]
    public bool CanSync { get; set; }

    public bool AgreedTerms { get; set; }
    public bool Deleted { get; set; }
}

public class UserContext : IdentityStoreContext
{
    public UserContext(DbContext db)
        : base(db)
    {
        this.Users = new UserStore<User>(this.DbContext);
    }
}

public class UserDbContext : IdentityDbContext<User, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
}

在我的AccountController构造函数中我有:

    public AccountController() 
    {
        IdentityStore = new IdentityStoreManager(new UserContext(new UserDbContext()));
        AuthenticationManager = new IdentityAuthenticationManager(IdentityStore);
    }

就是这样,一切都按预期工作:)