ASP .NET Core 3.1 - Usando o Identity de cabo a rabo - XVI
Hoje vamos continuar a série de artigos mostrando como usar o ASP .NET Core Identiy na versão 3.1 da ASP .NET .Core e do EF Core. |
|
Continuando a décima quinta parte do artigo veremos como adicionar e remover usuários de uma role.
Incluindo e removendo usuários de uma role
Na view EditRole que criamos na aula anterior definimos o botão para remover e/ou adicionar um usuário para a role selecionada.
Quando o usuário clicar no botão Incluir/Remover usuário vamos exibir a lista de usuários existentes na role com um checkbox, e os botões para Atualizar ou Cancelar a operação.
Se você quiser que o usuário seja membro da role basta marcar o checkbox e clicar no botão Atualizar que a tabela AspNetUserRoles do banco de dados será atualizada. Esta tabela esta relacionada com as tabelas AspNetUsers e AspNetRoles.
Assim vamos entender como funciona o relacionamento entre as tabelas AspNetUsers, AspNetUserRoles e AspNetRoles.
Os usuários da aplicação são armazenados na tabela AspNetUsers, as roles são armazenadas na tabela AspNetRoles, e, na tabela AspNetUserRoles temos o mapeamento entre os usuários e as suas roles.
O relacionamento entre as tabelas é feito pelo Id do usuário com a coluna UserId e a coluna RoleId com o Id da role:
Assim existe um relacionamento muitos-para-muitos entre as tabelas, e, a tabela AspNetUserRoles é a tabela de junção:
Neste
relacionamento muitos-para-muitos um usuário pode ser um membro de várias
roles e uma role pode conter muitos usuários como membros.
As duas colunas da tabela AspNetUserRoles: UserId e RoleId
são ambas chaves estrangeiras.
Precisamos expressar esse relacionamento criando a viewmodel UserRoleViewModel na pasta ViewModels:
public class UserRoleViewModel
{
public string UserId { get; set; }
public string UserName { get; set; }
public bool IsSelected { get; set; }
}
|
Definimos nesta classe as propriedade UserId, UserName e IsSelected. Onde:
Poderíamos incluir a propriedade RoleId também na classe UserRoleViewModel, mas no que diz respeito a essa view, existe um relacionamento de um para muitos de Role para Users. Portanto, para não repetir o RoleId para cada usuário, usaremos o recurso ViewBag para passar o RoleId do controlador para a view.
Agora podemos criar o método Action EditUsersInRole() que vai implementar a inclusão e remoção de um usuário na role. Vamos começar com o método HttpGet:
[HttpGet]
public async Task<IActionResult> EditUsersInRole(string roleId)
{
ViewBag.roleId = roleId;
var role = await roleManager.FindByIdAsync(roleId);
if (role == null)
{
ViewBag.ErrorMessage = $"Role com Id = {roleId} não foi encontrada";
return View("NotFound");
}
var model = new List<UserRoleViewModel>();
var listaUsuarios = userManager.Users.ToList(); foreach (var user in listaUsuarios)
{
var userRoleViewModel = new UserRoleViewModel
{
UserId = user.Id,
UserName = user.UserName
};
if (await userManager.IsInRoleAsync(user, role.Name))
{
userRoleViewModel.IsSelected = true;
}
else
{
userRoleViewModel.IsSelected = false;
}
model.Add(userRoleViewModel);
}
return View(model);
}
|
No código deste método Action estamos recebendo o ID da role via URL e a seguir armazenamos em um ViewBag.
Localizamos a role pelo seu ID, e, se ela não for encontrada retornamos um NotFound.
Listamos os usuários existentes na role e usando o método IsInRoleAsycn(user,role.Name) verificamos se o usuário pertence ou não à role e atribuímos o valor true ao checkbox caso o usuário pertença à role.
A seguir o método Action EditUsersInRole HttpPost:
[HttpPost]
public async Task<IActionResult> EditUsersInRole(List<UserRoleViewModel> model, string roleId)
{
var role = await roleManager.FindByIdAsync(roleId);
if (role == null)
{
ViewBag.ErrorMessage = $"Role com Id = {roleId} não foi encontrada";
return View("NotFound");
}
for (int i = 0; i < model.Count; i++)
{
var user = await userManager.FindByIdAsync(model[i].UserId);
IdentityResult result = null;
if (model[i].IsSelected && !(await userManager.IsInRoleAsync(user, role.Name)))
{
result = await userManager.AddToRoleAsync(user, role.Name);
}
else if (!model[i].IsSelected && await userManager.IsInRoleAsync(user, role.Name))
{
result = await userManager.RemoveFromRoleAsync(user, role.Name);
}
else
{
continue;
}
if (result.Succeeded)
{
if (i < (model.Count - 1))
continue;
else
return RedirectToAction("EditRole", new { Id = roleId });
}
}
return RedirectToAction("EditRole", new { Id = roleId });
}
|
No método HttpPost da Action usamos o método IsInRoleAsync() para verificar se o usuário pertence à role, o método AddToRoleAsync() para incluir o usuário na role e o método RemoveFromRoleAsync() para remover o usuário da role. Esses métodos são da classe UserManager.
Para concluir vamos criar a view EditUsersInRole:
@model List<UserRoleViewModel>
@{
var roleId = ViewBag.roleId;
}
<form method="post">
<div class="card">
<div class="card-header">
<h2>Incluir ou remover usuários desta role</h2>
</div>
<div class="card-body">
@for (int i = 0; i < Model.Count; i++)
{
<div class="form-check m-1">
<input type="hidden" asp-for="@Model[i].UserId" />
<input type="hidden" asp-for="@Model[i].UserName" />
<input asp-for="@Model[i].IsSelected" class="form-check-input" />
<label class="form-check-label" asp-for="@Model[i].IsSelected">
@Model[i].UserName
</label>
</div>
}
</div>
<div class="card-footer">
<input type="submit" value="Atualizar" class="btn btn-primary" style="width:auto" />
<a asp-action="EditRole" asp-route-id="@roleId"
class="btn btn-primary" style="width:auto">Cancelar</a>
</div>
</div>
</form>
|
Agora precisamos ajustar o código da view EditRole e definir no botão Incluir/Remover Usuário a chamada ao método Action EditUsersInRole no controlador Administration passando o ID da role :
...
<div
class="card-footer"> |
Vamos executar o projeto e navegar para http://localhost:xxxx/administration/listroles para obter a lista de roles:
Agora vamos clicar no botão Editar para exibir os dados da role Admin selecionada pelo seu ID para edição:
Agora clique no botão Incluir/Remover Usuário :
Note que é passado o ID a role na URL e é exibido o usuário existente.
Agora podemos incluir esse usuário na role Admin marcando o checkbox e clicando no botão Atualizar.
Agora vemos que o usuário faz parte da role Admin e esta sendo exibido na view EditRole.
No próximo artigo vamos implementar a exclusão de uma role existente.
Pegue o projeto aqui: IdentityTotal_Roles_Users.zip (sem as referências)
"Sede unânimes
entre vós; não ambicioneis coisas altas, mas acomodai-vos às humildes; não
sejais sábios em vós mesmos;"
Romanos 12:16
Referências:
ASP .NET Core - Implementando a segurança com ... - Macoratti
ASP.NET Core MVC - Criando um Dashboard ... - Macoratti.net
C# - Gerando QRCode - Macoratti
ASP .NET - Gerando QRCode com a API do Google