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


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 sexta parte do artigo veremos como excluir uma role existente.

Excluindo uma role existente

Atualmente estamos exibindo na view ListRoles todas as roles existentes onde já implementamos a edição de uma role existente. Agora vamos implementar a exclusão de um role.

Para isso teremos que fazer o seguinte:

  1. Criar um método Action HttpPost DeleteRole para excluir a role;
  2. Criar uma view solicitando a confirmação do usuário para excluir a role;
  3. Definir no botão Deletar da view ListRoles a chamada ao método Action DeleteRole passando o Id da role;

Vamos iniciar criando o método Action DeleteRole no controlador AdministrationController:

        [HttpPost]
        public async Task<IActionResult> DeleteRole(string id)
        {
            var role = await roleManager.FindByIdAsync(id);
            if (role == null)
            {
                ViewBag.ErrorMessage = $"Role com Id = {id} não foi encontrada";
                return View("NotFound");
            }
            else
            {
                var result = await roleManager.DeleteAsync(role);
                if (result.Succeeded)
                {
                    return RedirectToAction("ListRoles");
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError("", error.Description);
                }
                return View("ListRoles");
            }
        }

Neste método Action recebemos o ID da role na URL e procuramos pela role usando o método FindByIdAsync().

Se a role for encontrada usamos o método DeleteAsync() para excluir a role e retornamos para a view ListRoles.

Agora precisamos ajustar o código da view ListRoles para que quando o usuário clicar no botão para deletar a role seja postado um formulário solicitando a confirmação da exclusão.

Assim vamos substituir o código dos botões para Editar e Deletar a role na view ListRoles pelo trecho de código abaixo:

...       
           <div class="card-footer">
                <form asp-action="DeleteRole" asp-route-id="@role.Id" method="post">
                    <a asp-action="EditRole" asp-controler="Administration"
                       asp-route-id="@role.Id" class="btn btn-primary">Editar</a>
                    <span id="confirmaDeletaSpan_@role.Id" style="display:none">
                        <span>Confirma a exclusão desta role ?</span>
                        <button type="submit" class="btn btn-danger">Sim</button>
                        <a href="#" class="btn btn-primary"
                           onclick="confirmaDelete('@role.Id', false)">Não</a>
                    </span>
                    <span id="deletaSpan_@role.Id">
                        <a href="#" class="btn btn-danger"
                           onclick="confirmaDelete('@role.Id', true)">Deletar</a>
                    </span>
                </form>
            </div>
...

Assim vamos entender o que foi feito:

Dentro da div card do bootstrap incluímos um formulário com o método post que írá invocar o método Action DeleteRole passando o Id da role:

 <form asp-action="DeleteRole" asp-route-id="@role.Id" method="post">

Vamos usar o método POST pois o método GET não deve alterar o estado no servidor, assim um Delete deve ser feito sempre usando um POST e não um GET.

A seguir temos o botão para editar uma role que já implementamos anteriormente.

A seguir estamos usando um span para expandir o espaço e exibir a mensagem de confirmação da exclusão onde no evento onclick do botão definimos o código JavaScript ConfirmaDelete() que iremos implementar a seguir:

	      <span id="confirmaDeleteSpan_@role.Id" style="display:none">
                        <span>Confirma a exclusão desta role ?</span>
                        <button type="submit" class="btn btn-danger">Sim</button>
                        <a href="#" class="btn btn-primary"
                           onclick="confirmaDelete('@role.Id', false)">Não</a>
                    </span>
                    <span id="deleteSpan_@role.Id">
                        <a href="#" class="btn btn-danger"
                           onclick="confirmaDelete('@role.Id', true)">Deletar</a>
                    </span>

Os elementos SPAN que cercam os botões Deletar, Sim e Não serão gerados dinamicamente para todas as roles existentes.

Se você tiver mais de uma role na página, haverá mais de um elemento de SPAN, e, para garantir que esses elementos SPAN possuam IDs exclusivos, anexamos o User.Id, que é um Guid e assim teremos valores únicos.

Note também que o botão 'Sim' foi definido como do tipo 'submit' para submeter o formulário e fazer o POST.

Agora vamos criar o script JavaScript para confirmar a exclusão da role. Para isso vamos criar dentro da pasta wwwroot/js o arquivo CustomScript.js com o código da função confirmaDelete:

function confirmaDelete(uniqueId, isDeleteClicked) {
    var deleteSpan = 'deleteSpan_' + uniqueId;
    var confirmaDeleteSpan = 'confirmaDeleteSpan_' + uniqueId;
    if (isDeleteClicked) {
        $('#' + deleteSpan).hide();
        $('#' + confirmaDeleteSpan).show();
    } else {
        $('#' + deleteSpan).show();
        $('#' + confirmaDeleteSpan).hide();
    }
}

Esta função recebe o ID da SPAN de onde extraímos o ID da role e true ou false conforme a escolha do usuário, e,  com base nisso oculta ou exibe os botões.

Precisamos exibir esta função JavaScript confirmaDelete apenas na view ListRoles e para isso vamos incluir nesta view a seção opcional de Scripts para incluir o arquivo CustomScript.js que criamos na pasta wwwroot/js do projeto e que contém esta função.

Assim inclua no final do arquivo ListRoles.cshtml o código abaixo:

@section Scripts {
    <script src="~/js/CustomScript.js"></script>
}

Após concluir esta implementação podemos testar a nossa aplicação executando o projeto e acessando a url : https://localhost:xxxx/administration/listroles

Primeiro vamos incluir uma nova role chamada Teste e a seguir vamos excluir esta role para testar a nossa implementação.

Veja abaixo o resultado:

Vemos que nossa implementação esta funcionando.

Mas vou deixar  uma pergunta que iremos responder mais adiante no curso : "Quando eu removo uma role, todos os seus usuários são excluídos também ? Por que ? "

No próximo artigo vamos implementar a exibição do menu com base no perfil do usuário.

"Portanto, cingindo os lombos do vosso entendimento, sede sóbrios, e esperai inteiramente na graça que se vos ofereceu na revelação de Jesus Cristo;"
1 Pedro 1:13

Referências:


José Carlos Macoratti