Asp.Net Identity - IdentityDbContext<TUser> causando problemas para campos adicionados à tabela AspNetRoles
-
21-12-2019 - |
Pergunta
IdentityDbContext causando problemas para propriedades/campos adicionados ao AspNetRoles
Acredito que o problema esteja aqui com IdentityDbContext assumindo um tipo IdentityUser:
public class MyIdentityDb : IdentityDbContext<ApplicationUser>
{
public IdentityDb()
: base("IdentityDb")
{
}
}
Mas deixe-me explicar…
É maravilhoso podermos adicionar campos à tabela AspNetUsers adicionando propriedades à nossa classe ApplicationUser que herda de IdentityUser.Exemplo:
public class ApplicationUser : IdentityUser
{
[Required]
[StringLength(50)]
public string FirstName { get; set; }
[Required]
[StringLength(50)]
public string LastName { get; set; }
}
É tão natural que possamos adicionar campos à tabela AspNetRoles adicionando propriedades a uma classe ApplicationRole que herda de IdentityRole.Exemplo:
public class ApplicationRole : IdentityRole
{
[Required]
[StringLength(50)]
public string ProperName { get; set; }
}
Funciona perfeitamente.Podemos ver o campo no banco de dados.Podemos adicionar dados a ele.Exemplo:
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);
Mas agora nos deparamos com um problema ao tentar obter os dados.Exemplo:
Nosso ViewModel:
public class IndexViewModel
{
public IList<ApplicationUser> Users { get; set; }
public IList<ApplicationRole> Roles { get; set; }
}
Em nosso controlador:
private MyIdentityDb myIdentityDb = new MyIdentityDb();
Nosso método Index em nosso controlador:
public ViewResult Index(int? page)
{
return View(new IndexViewModel
{
Users = myIdentityDb.Users.ToList(),
Roles = myIdentityDb.Roles.ToList()
});
}
O erro está em “myIdentityDb.Roles.ToList()” e diz “Não é possível converter implicitamente o tipo System.Collection.Generic.List<Microsoft.AspNet.Identity.EntityFramework.IdentityRole> to System.Collections.Generic.IList<MyApp.Models.ApplicationRole>
…
É claro que poderíamos alterar nosso ViewModel para usar o tipo IdentityRole como no exemplo a seguir, mas não poderemos chegar ao novo campo “ProperName” na tabela AspNetRoles:
public class IndexViewModel
{
public IList<ApplicationUser> Users { get; set; }
public IList<IdentityRole> Roles { get; set; }
}
Portanto, poderíamos tentar criar outra classe Db e passar para ela um tipo IdentityRole em vez de IdentityUser:
public class MyIdentityDb : IdentityDbContext<ApplicationUser>
{
public MyIdentityDb()
: base("MyIdentityDb")
{
}
}
public class MyIdentityRolesDb : IdentityDbContext<ApplicationRole>
{
public MyIdentityRolesDb()
: base("MyIdentityDb")
{
}
}
E mude nosso controlador:
private MyIdentityDb myIdentityDb = new MyIdentityDb();
private MyIdentityRolesDb myIdentityRolesDb = new MyIdentityRolesDb();
E altere nosso método Index em nosso controlador:
public ViewResult Index(int? page)
{
return View(new IndexViewModel
{
Users = myIdentityDb.Users.ToList(),
Roles = myIdentityRolesDb.Roles.ToList()
});
}
Mas acabamos com o mesmo problema;o fato de IdentityDbContext assumir um tipo IdentityUser.
Alguma idéia de como podemos obter uma lista de funções com os campos/propriedades personalizados?
Solução
Portanto, se você atualizar para os pacotes beta 2.0.0, poderá obter um IQueryable de ApplicationRole diretamente do gerenciador de funções:
roleManager.Roles
Portanto, você não precisa ir até o contexto do banco de dados, essa era uma limitação na versão 1.0 que foi corrigida na versão 2.0.
Outras dicas
Por favor, dê uma olhada no seguinte artigo que explica em detalhes o que você está tentando fazer http://typecastexception.com/post/2014/02/13/ASPNET-MVC-5-Identity-Extending-and-Modifying-Roles.aspx