A More Mature User (model)

by MikeHogg12. August 2012 09:52

My MVVM and MVC User models have usually been a hierarchy of different classes starting with the simplest name/password and adding more properties with each inherited subclass. 

 

(Side Note: I've noticed a tendency to add more properties to different versions of subclasses can get out of hand, mucking up a membership provider, when mixed with Roles, when what is really called for is a Profile provider for all those descriptive properties.  See Decorate Pattern and MS ProfileProvider.)

 

 

 

This time a client requirement surprised me by making even username/password optional, which I've never done.  As a matter of fact, most of my user hierarchy was built to support the base class of required properties using MVC DataAnnotation Required Attributes.  So

 

I rewrote it as one base User with no requireds, and then various subclasses more like ViewModels.  Also I Interfaced the User and changed all my Membership and Repository arguments to the interface.  Now this pattern seems much more flexible, simple, and easily extensible.  Don't know why I didn't see this before.

 

 

public interface IUserModel
    {
int Id { get; set; }
string EmailAddress { get; set; }
string Password { get; set; } 
bool Active { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
string PhoneNumber { get; set; }
bool GetsEmail { get; set; }
        IEnumerable<RoleModel> Roles { get; set; }
    }
    [Serializable]
public class UserModel : IUserModel
    {
        [Key]
public int Id { get; set; }
        [Display(Name = "Email Address")]
        [StringLength(255)]
        [MyLibrary.Web.Mvc3.Attributes.EmailAddress]
public virtual string EmailAddress { get; set; }
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
public virtual string Password { get; set; }
        [Display(Name = "Active")]
public bool Active { get; set; }
        [Display(Name = "First name")]
        [StringLength(50)]
public virtual string FirstName { get; set; }
        [Display(Name = "Last name")]
        [StringLength(50)]
public string LastName { get; set; }
        [StringLength(255)]
        [Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
        [Display(Name = "Gets Emails?")]
public bool GetsEmail { get; set; }
        [Display(Name = "Roles")]
public IEnumerable<RoleModel> Roles { get; set; }
    }
public class LogOnModel : UserModel
    {
        [Required]
        [Display(Name = "Email Address")]
        [StringLength(255)]
        [MyLibrary.Web.Mvc3.Attributes.EmailAddress]
public override string EmailAddress { get; set; }
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
public override string Password { get; set; }
    }
public class RegisterModel : LogOnModel
    { 
        [Required(ErrorMessage = "Please enter a first name")]
public override string FirstName { get; set; }
        [DataType(DataType.Password)]
        [Compare("Password")]
        [Display(Name = "Confirm Password")]
public string PasswordConfirm { get; set; }
    }
public class ChangePasswordModel : UserModel
    {
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Old Password")]
public string OldPassword { get; set; }
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
public override string Password { get; set; }
        [DataType(DataType.Password)]
        [Compare("Password")]
        [Display(Name = "Confirm Password")]
public string PasswordConfirm { get; set; }
    }
public class FoundPasswordModel : UserModel
    {
        [Required] 
public override string EmailAddress { get; set; }
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
public override string Password { get; set; }
        [DataType(DataType.Password)]
        [Compare("Password")]
        [Display(Name = "Confirm Password")]
public string PasswordConfirm { get; set; }
    }
public class ValidatedUserModel : UserModel
    {
        [Required]        [StringLength(255)]
        [MyLibrary.Web.Mvc3.Attributes.EmailAddress] public override string EmailAddress { get; set; }
        [Required(ErrorMessage = "Please enter a first name")]
public override string FirstName { get; set; }
public ValidatedUserModel() { }
public ValidatedUserModel(IUserModel user)
        {
            Active = user.Active;
            EmailAddress = user.EmailAddress;
            FirstName = user.FirstName;
            GetsEmail = user.GetsEmail;
            Id = user.Id;
            LastName = user.LastName;
            PhoneNumber = user.PhoneNumber;
            Roles = user.Roles;
        }
    }

Add comment

biuquote
  • Comment
  • Preview
Loading

About Mike Hogg

Mike Hogg is a c# developer in Brooklyn.

More Here

Favorite Books

This book had the most influence on my coding style. It drastically changed the way I write code and turned me on to test driven development even if I don't always use it. It made me write clearer, functional-style code using more principles such as DRY, encapsulation, single responsibility, and more.amazon.com

This book opened my eyes to a methodical and systematic approach to upgrading legacy codebases step by step. Incrementally transforming code blocks into testable code before making improvements. amazon.com

More Here