tett
tett

Reputation: 605

How can I create two types of users in MVC5?

I'm creating MVC5 app, and I'm already using ASP.NET Identity to create users. So, I already have the AspNetUsers table, and whenever user registers I get an entry there. I also have an Admin role, where I manually specify, which registered user is an admin. On the other hand, I also need to register Businesses, and much like normal Users, they will be able to log-in, register, and do some stuff. The point is that they will have both some similar and different fields with/from the normal users. For example, they will also have, e-mail address, password (which I want to be hashed like for normal users), e-mail confirmation, unique id etc. But they have different fields for more information, like their address, zip, country, category, etc. which normal users don't have. How can I achieve this in MVC?

Should I do something like the ApplicationUser class?

public class ApplicationUser : IdentityUser

I mean, should I inherit my Business model from the IdendityUser? If yes, how will my model know which of the fields from IdentityUser to use and which not?

Here is my current Business model:

public class Business
{
    public int BusinessID { get; set; }

    public string BusinessName { get; set; }

    [ForeignKey("Category")]
    public int CategoryID { get; set; }

    public virtual Category Category { get; set; }

    [ForeignKey("Subcategory")]
    public int SubcategoryID { get; set; }

    public virtual Subcategory Subcategory { get; set; }

    public string BusinessAddress { get; set; }

    public string BusinessZip { get; set; }

    public string BusinessPhone { get; set; }

    public string BusinessDescription { get; set; }

    public string Facebook { get; set; }

    public string Twitter { get; set; }

    public byte[] ImageData { get; set; }

    public string ImageMimeType { get; set; }

    [Range(0.0, 5.0)]
    public double BusinessRating { get; set; }

    public virtual ICollection<Review> Reviews { get; set; }
}

So, apart from those fields, I want my table to include the stuff similar to AspNetUsers, like Email, EmailConfirmed, PasswordHash, SecurityStamp, etc.

EDIT:

Please note that some of my fields in the Business model are required. And also below you can find my ApplicationUser class.

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

Upvotes: 2

Views: 1238

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239210

Use simple inheritance:

public class Business : ApplicationUser
{
    ...
}

You'll end up with a Discriminator column in your AspNetUsers table that will help Entity Framework identity which class it should instantiate for the row (Business or ApplicationUser). Then you can either just query as normal or if you only want one particular type or another, you can use OfType<T>:

var businessUsers = db.Users.OfType<Business>();

Note: By default, Entity Framework handles simple inheritance with a single table with a Discriminator column. For most cases this works just fine, but you must keep in mind that any property you add to subclasses of your base class, must be nullable. You cannot require something like a DateTime on Business to be required at the database-level, because then you could never save an ApplicationUser, which does not that property. However, this is only an issue at the database-level. You can still use view models to make a particular property on Business required from a front-end perspective.

Upvotes: 2

Related Questions