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


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 nona parte do artigo veremos como editar os usuários cadastrados.

Editando os usuários cadastrados

Já estamos listando os usuários usando a view ListUsers conforme a figura abaixo:

Agora vamos implementar a edição do usuário, de forma que quando o botão Editar for clicado vamos invocar o método Action EditUser que iremos criar a seguir no controlador AdministrationController.

Assim vamos primeiro ajustar o código relacionado com o botão Editar definido a seguir:

...
  <div class="card-footer">
                <a asp-action="EditUser" asp-controller="Administration"
                   asp-route-id="@user.Id" class="btn btn-primary">Editar</a>
                <a href="#" class="btn btn-danger">Deletar</a>
  </div>
...

Antes de criamos o método Action temos que definir uma ViewModel EditUserViewModel que representa o usuário que vamos editar. Para isso crie a classe EditUserViewModel na pasta ViewModels com o código a seguir:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace FuncionariosWeb.ViewModels
{
    public class EditUserViewModel
    {
        public EditUserViewModel()
        {
            Claims = new List<string>();
            Roles = new List<string>();
        }
        public string Id { get; set; }
        
        [Required(ErrorMessage = "O nome do usuário é obrigatório")]
        public string UserName { get; set; }
        [Required(ErrorMessage = "O nome email é obrigatório")]
        [EmailAddress(ErrorMessage = "Email inválido")]
        public string Email { get; set; }

        public string Cidade { get; set; }
        public List<string> Claims { get; set; }
        public IList<string> Roles { get; set; }
    }
}

A classe EditUserViewModel, além das propriedades UserName, Email , Cidade também precisa gerenciar as Roles do usuário e as suas Claims, por isso definimos as propriedades Claims e Roles como uma lista de string.

Nota: As Claims são declarações que são feitas sobre o usuário.

Agora podemos criar o método Action EditUser. Primeiro vamos definir o método GET:

        [HttpGet]
        public async Task<IActionResult> EditUser(string id)
        {
            var user = await userManager.FindByIdAsync(id);
            if (user == null)
            {
                ViewBag.ErrorMessage = $"Usuário com Id = {id} não foi encontrado";
                return View("NotFound");
            }
            // GetClaimsAsync retorna a lista de Claims
            var userClaims = await userManager.GetClaimsAsync(user);
            // GetRolesAsync retorna a lista de Roles
            var userRoles = await userManager.GetRolesAsync(user);
            var model = new EditUserViewModel
            {
                Id = user.Id,
                Email = user.Email,
                UserName = user.UserName,
                Cidade = user.Cidade,
                Claims = userClaims.Select(c => c.Value).ToList(),
                Roles = userRoles
            };
            return View(model);
        }

Este método faz as alterações no usuário e posta o formulário.

Agora vejamos a implementação do método EditUser POST:

        [HttpPost]
        public async Task<IActionResult> EditUser(EditUserViewModel model)
        {
            var user = await userManager.FindByIdAsync(model.Id);
            if (user == null)
            {
                ViewBag.ErrorMessage = $"Usuário com Id = {model.Id} não foi encontrado";
                return View("NotFound");
            }
            else
            {
                user.Email = model.Email;
                user.UserName = model.UserName;
                user.Cidade = model.Cidade;
                var result = await userManager.UpdateAsync(user);
                if (result.Succeeded)
                {
                    return RedirectToAction("ListUsers");
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error.Description);
                }
                return View(model);
            }
        }      

O método Post recebe os dados postados e usa o método UpdateAsync() para atualizar os dados.

Vamos agora alterar o código do método Action Register do controlador AccountController para verificar se o usuário logado faz parte do perfil Admin e neste caso vamos direcioná-lo para o método Action ListRoles.

@model EditUserViewModel
@{
    ViewBag.Title = "Edita Usuário";
}
<h3>Usuário</h3>
<form method="post" class="mt-3">
    <div class="form-group row">
        <label asp-for="Id" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Id" disabled class="form-control">
        </div>
    </div>
    <div class="form-group row">
        <label asp-for="Email" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Email" class="form-control">
            <span asp-validation-for="Email" class="text-danger"></span>
        </div>
    </div>
    <div class="form-group row">
        <label asp-for="UserName" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="UserName" class="form-control">
            <span asp-validation-for="UserName" class="text-danger"></span>
        </div>
    </div>
    <div class="form-group row">
        <label asp-for="Cidade" class="col-sm-2 col-form-label"></label>
        <div class="col-sm-10">
            <input asp-for="Cidade" class="form-control">
        </div>
    </div>
    <div asp-validation-summary="All" class="text-danger"></div>
    <div class="form-group row">
        <div class="col-sm-10">
            <button type="submit" class="btn btn-primary">Atualiza</button>
            <a asp-action="ListUsers" class="btn btn-primary">Cancela</a>
        </div>
    </div>
    <div class="card">
        <div class="card-header">
            <h3>Roles</h3>
        </div>
        <div class="card-body">
            @if (Model.Roles.Any())
            {
                foreach (var role in Model.Roles)
                {
                    <h5 class="card-title">@role</h5>
                }
            }
            else
            {
                <h5 class="card-title">Sem roles</h5>
            }
        </div>
        <div class="card-footer">
            <a href="#" style="width:auto" class="btn btn-primary">
                Gerencia Roles
            </a>
        </div>
    </div>
    <div class="card mt-3">
        <div class="card-header">
            <h3>Claims</h3>
        </div>
        <div class="card-body">
            @if (Model.Claims.Any())
            {
                foreach (var claim in Model.Claims)
                {
                    <h5 class="card-title">@claim</h5>
                }
            }
            else
            {
                <h5 class="card-title">Sem claims</h5>
            }
        </div>
        <div class="card-footer">
            <a href="#" style="width:auto" class="btn btn-primary">
                Gerencia Claims
            </a>
        </div>
    </div>
</form>

Nesta view exibimos os dados do usuário selecionado para edição e também suas roles e suas claims.

Agora é só alegria...

Executando o projeto temos e selecionando um usuário para edição temos o resultado a seguir:

No próximo artigo vamos mostrar como deletar usuários cadastrados.

"Se alguém ouvir as minhas palavras e não as guardar, eu não o julgo; porque eu não vim para julgar o mundo, e sim para salvá-lo.
Quem me rejeita e não recebe as minhas palavras tem quem o julgue; a própria palavra que tenho proferido, essa o julgará no último dia."
João 12:47,48

Referências:


José Carlos Macoratti