ASP .NET Core 3.1 - Usando o Identity de cabo a rabo - XXIV


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 vigésima terceira parte do artigo veremos como gerenciar as roles dos usuários.

Gerenciando as roles dos usuários

Agora veremos como adicionar ou remover roles para um dados usuário usando a API Identity.

Quando implementamos a exibição dos usuários ao editar um usuário temos a view exibida a seguir:

Para gerenciar as roles do usuário, quando o botão - Gerencia Roles - for acionado vamos direcionar o usuário para a view ManageUserRoles.

Para isso vamos incluir o código abaixo na view EditUser.cshtml no botão para gerenciar as roles:

 <div class="card-footer">
            <a asp-action="ManageUserRoles" asp-route-userId="@Model.Id"
               class="btn btn-primary">
                Gerenciar Roles
            </a>
 </div>

O próximo passo será criar o método Action ManagaerUserRoles mas antes precisamos criar a view Model UserRolesViewModel que vamos usar para exibir as informações das roles do usuário.

Na pasta ViewModels crie a classe UserRolesViewModel com o código abaixo:

    public class UserRolesViewModel
    {
        public string RoleId { get; set; }
        public string RoleName { get; set; }
        public bool IsSelected { get; set; }
    }

Nesta classe temos a propriedade RoleName usada para exibir o nome da role e a propriedade IsSelected usada para  determinar se a role está selecionada para ser atribuída ao usuário especificado.

Poderíamos incluir a propriedade UserId também na classe UserRolesViewModel, mas no que diz respeito a essa exibição, existe um relacionamento um-para-muitos de User para Roles. Portanto, para não repetir o UserId para cada role, usaremos um ViewBag para passar o UserId do controlador para a view.

Agora vamos criar o método Action ManageUserRoles no controlador AdministrationController.

Primeiro vamos definir o HttpGet:

        [HttpGet]
        public async Task<IActionResult> ManageUserRoles(string userId)
        {
            ViewBag.userId = userId;
            var user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                ViewBag.ErrorMessage = $"Usuário com Id = {userId} não foi encontrado";
                return View("NotFound");
            }
            var model = new List<UserRolesViewModel>();
            foreach (var role in roleManager.Roles)
            {
                var userRolesViewModel = new UserRolesViewModel
                {
                    RoleId = role.Id,
                    RoleName = role.Name
                };
                if (await userManager.IsInRoleAsync(user, role.Name))
                {
                    userRolesViewModel.IsSelected = true;
                }
                else
                {
                    userRolesViewModel.IsSelected = false;
                }
                model.Add(userRolesViewModel);
            }
            return View(model);
        }

Neste código localizamos o usuário pelo id e obtemos cada role para o usuário selecionado exibindo-a na view.

Agora temos o código do método HttpPost para o mesmo método Action:

        [HttpPost]
        public async Task<IActionResult> ManageUserRoles(List<UserRolesViewModel> model, string userId)
        {
            var user = await userManager.FindByIdAsync(userId);
            if (user == null)
            {
                ViewBag.ErrorMessage = $"Usuário com Id = {userId} não foi encontrado";
                return View("NotFound");
            }
            var roles = await userManager.GetRolesAsync(user);
            var result = await userManager.RemoveFromRolesAsync(user, roles);
            if (!result.Succeeded)
            {
                ModelState.AddModelError("", "Não foi possível remover a role do usuário");
                return View(model);
            }
            result = await userManager.AddToRolesAsync(user,
                model.Where(x => x.IsSelected).Select(y => y.RoleName));
            if (!result.Succeeded)
            {
                ModelState.AddModelError("", "Não foi possível incluir a role ao usuário");
                return View(model);
            }
            return RedirectToAction("EditUser", new { Id = userId });
        }

No código acima estamos recebendo o código do usuário e as roles que foram marcadas ou desmarcadas indicando se serão incluídas ou removidas das roles deste usuário.

Obtemos as roles para o usuário e removemos o usuário das roles. A seguir adicionamos o usuário apenas às roles selecionadas e retornamos para a view EditUser.

Agora vamos criar a view ManageUserRoles conforme código a seguir:

@model List<UserRolesViewModel>
@{
    var userId = ViewBag.userId;
}
<form method="post">
    <div class="card">
        <div class="card-header">
            <h2>Gerencia Roles do Usuário</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].RoleId" />
                    <input type="hidden" asp-for="@Model[i].RoleName" />
                    <input asp-for="@Model[i].IsSelected" class="form-check-input" />
                    <label class="form-check-label" asp-for="@Model[i].IsSelected">
                        @Model[i].RoleName
                    </label>
                </div>
            }
            <div asp-validation-summary="All" class="text-danger"></div>
        </div>
        <div class="card-footer">
            <input type="submit" value="Atualiza" class="btn btn-primary"
                   style="width:auto" />
            <a asp-action="EditUser" asp-route-id="@userId"
               class="btn btn-primary" style="width:auto">Cancela</a>
        </div>
    </div>
</form>

Agora podemos executar o projeto e testar a funcionalidade implementada conforme mostrado a seguir:

No próximo artigo veremos como gerenciar as claims dos usuários na ASP .NET Core Identity.

Pegue o projeto aqui: IdentityTotal_GerenciaUserRoles.zip (sem as referências)

"E nós conhecemos, e cremos no amor que Deus nos tem. Deus é amor; e quem está em amor está em Deus, e Deus nele."
1 João 4:16

Referências:


José Carlos Macoratti