IdentityDbContext causing problems for properties/fields added to AspNetRoles
I believe the problem is here with IdentityDbContext taking an IdentityUser type:
public class MyIdentityDb : IdentityDbContext<ApplicationUser>
{
public IdentityDb()
: base("IdentityDb")
{
}
}
But let me explain…
It is wonderful that we can add fields to the AspNetUsers table by adding properties to our ApplicationUser class that inherits from IdentityUser. Example:
public class ApplicationUser : IdentityUser
{
[Required]
[StringLength(50)]
public string FirstName { get; set; }
[Required]
[StringLength(50)]
public string LastName { get; set; }
}
So natural we can add fields to the AspNetRoles table by adding properties to an ApplicationRole class that inherits from IdentityRole. Example:
public class ApplicationRole : IdentityRole
{
[Required]
[StringLength(50)]
public string ProperName { get; set; }
}
Works perfect. We can see the field in the database. We can add data to it. Example:
RoleManager<ApplicationRole> roleManager = new RoleManager<ApplicationRole>(new RoleStore<ApplicationRole>(new MyIdentityDb()));
var role = new ApplicationRole() { Name = name, ProperName = propername };
var result = await roleManager.CreateAsync(role);
But now we run into a problem when trying to get to the data. Example:
Our ViewModel:
public class IndexViewModel
{
public IList<ApplicationUser> Users { get; set; }
public IList<ApplicationRole> Roles { get; set; }
}
On our Controller:
private MyIdentityDb myIdentityDb = new MyIdentityDb();
Our Index method on our controller:
public ViewResult Index(int? page)
{
return View(new IndexViewModel
{
Users = myIdentityDb.Users.ToList(),
Roles = myIdentityDb.Roles.ToList()
});
}
The error is on “myIdentityDb.Roles.ToList()” and reads “Cannot implicitly convert type System.Collection.Generic.List<Microsoft.AspNet.Identity.EntityFramework.IdentityRole> to System.Collections.Generic.IList<MyApp.Models.ApplicationRole>
…
Of course we could change our ViewModel to use type IdentityRole like the following example, but then we cannot get to the new “ProperName” field in the AspNetRoles table:
public class IndexViewModel
{
public IList<ApplicationUser> Users { get; set; }
public IList<IdentityRole> Roles { get; set; }
}
So we could try creating another Db class and pass it an IdentityRole type instead of IdentityUser:
public class MyIdentityDb : IdentityDbContext<ApplicationUser>
{
public MyIdentityDb()
: base("MyIdentityDb")
{
}
}
public class MyIdentityRolesDb : IdentityDbContext<ApplicationRole>
{
public MyIdentityRolesDb()
: base("MyIdentityDb")
{
}
}
And change our controller:
private MyIdentityDb myIdentityDb = new MyIdentityDb();
private MyIdentityRolesDb myIdentityRolesDb = new MyIdentityRolesDb();
And change our Index method on our controller:
public ViewResult Index(int? page)
{
return View(new IndexViewModel
{
Users = myIdentityDb.Users.ToList(),
Roles = myIdentityRolesDb.Roles.ToList()
});
}
But we end up with the same problem; the fact that IdentityDbContext takes an IdentityUser type.
Any ideas how we can get a list of Roles with the custom fields/properties?
Please take a look at the following article which explains in detail what you are trying to do http://typecastexception.com/post/2014/02/13/ASPNET-MVC-5-Identity-Extending-and-Modifying-Roles.aspx
So if you upgrade to the 2.0.0 beta packages, you should be able to get an IQueryable of ApplicationRole directly from the role manager:
So you don't have to drop down to the DB context, this was a limitation in 1.0 that has been fixed in the 2.0 release.