Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include property on ASP.Net Identity 2.0 UserManager.Users.ToListAsync and UserManager.FindByIdAsync

I am trying to implement Asp.Net Identity 2.0. I have managed so far very well with the help of this blog. But I went a slightly different road. I want some data not to be part of the User object, but rather of a newly created Customer object. I want to keep the authentication and authorization data separate from my business data.

So in my case I modified the ApplicationUser class by adding a customer property:

    public Customer Customer { get; set; }

The Customer class looks like this:

public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Insertion { get; set; }
    public Gender Gender { get; set; }
    public DateTime Birthdate { get; set; }
    ...etc.
    public virtual ApplicationUser User { get; set; }
}

I also added the relationship in de the ApplicationDbContext:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasRequired(u => u.User);
        base.OnModelCreating(modelBuilder);

    }

So now after some modifications to the register viewmodel and the controller I am able to register as a user and have both a User record created in the AspNetUsers table and a Customer record in the Customer table with a reference to the User record. So far so good.

But now when I retrieve the user for example for display purposes the Customer property is empty. Which makes sense, since the underlying record is not loaded. Normally I would use the .Include keyword to load the related records. But I don't know how to do that when using the default UserManager that comes with Asp.Net identity 2.0.

Does anybody know how to achieve this?

like image 486
Mounhim Avatar asked Nov 20 '14 12:11

Mounhim


1 Answers

I found the answer. Probablu need more searching before answering. The answer is based on the answer in this SO Question

I have added a class called ApplicationUserStore.

public class ApplicationUserStore : UserStore<ApplicationUser>
{
    public ApplicationUserStore(DbContext context)
        : base(context)
    {
    }

    public override System.Threading.Tasks.Task<ApplicationUser> FindByIdAsync(string userId)
    {

        return Users.Include(u=>u.Customer).Include(u => u.Roles).Include(u => u.Claims).Include(u => u.Logins).FirstOrDefaultAsync(u => u.Id == userId);
    }
}

In this class I have overriden the FindByIdAsync to include the customer record.

Then I changed in IdentityConfig.cs the first line in the method Create which returns the ApplicationUserManager so that it passes the newly created ApplicationUserStore instead of the UserStore.

var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<ApplicationDbContext>()));

I probably also have to override some other fetching methods to include the customer records.

like image 115
Mounhim Avatar answered Nov 12 '22 07:11

Mounhim