Escolha uma Página
Populando Papéis (roles),usuários principais (admin,managers) e menus por papel a partir do Startup.cs do Core MVC

Populando Papéis (roles),usuários principais (admin,managers) e menus por papel a partir do Startup.cs do Core MVC

Populando Papéis (roles),usuários principais (admin,managers) e menus por papel a partir do Startup.cs do Core MVC

Muitas vezes você quer pré-definir os papéis (roles) para todos possíveis usuários da sua aplicação, Bem como definir um ou mais usuários com poder administrativo geral, ou também um usuário gerenciador, com menos poderes que o administrador. Este artigo mostra como fazer isso,

Ao rodar o arquivo STARTUP.CS é perfeitamente possível gerar todos os papéis (Roles( desejados para a sua aplicação, bem como definir ao menos um usuário administrativo com superpoderes e outros usuários com menores poderes. Isso vai ajudar, depois, a definir menus seletivos, onde só aparecem opções de navegação a que cada papel (role) dá direito.

Passo 1 – Nova tabela no banco de dados

Parimos do princípio que você já tem seu database com as tabelas que necessita, conforma artigos anteriores, O que vamos precisar agora é de uma nova tabela que contenha o que o menu de cada pape (role( deve conter ou não.. Ou seja, precisamos fazer uma tabela de relacionamento entre a tabela ASP.NET Roles e nossa tabela de menu. Vamos ver em detalhes sobre como criar nossa nova Tabela de Menus que tem um relacionamento com a tabela ASP.NET Identity AspNetRoles. A ess tabela vamos dar o nome MenuMaster, com os seguintes campos:

 

Tabela MenuMaster – Campos e Descrições

MenuIdentity é o campo de identidade usado como linha de ID (KEY)
MenuID é a identidade propriamente dita usada como referência primárias para qualquer campo do Menu
Parente_MenuID para cada top  MenuID será usado o valor “*”. Esse valor serpa usado somente para itens de menu com nível igual a 1 (primeira opção por default). Se na hierarquia de menus houver níveis 2 ou 3, elas farão referência ao menu raiz *MenuID”, que são pais
User_Rool Cria o menu para cada papel de usuário (User Role). O menu serpa mostrado para os usuários que tem esse papel (role) e que estiverem logados. Por exemplo, Admin pode criar diferentes menus para gerentes, consultores e outros papéis, E somente usuários que tenham esses papéis poderão ver esses menus
MenuFileName Este é o nome real para cada opção do menu (o que aparece em tela).  A ideia qui é usar o view nMWdo MV como MenuFileName
MenuURL É o Menu path para cada item do Menu, usado como hiperlink,, Em MVCé o nome do Controlador (controller)
USE_YN Se usado Y, o item de menu vai aparecer, Se usado N, não vai aparecer,  mesmo que ateda os requisitos de papel(role), Em geral é controlado por Viewbags, que definem se em certas condições do item de menu deve ou não aparecer,
CreateDate Data de criação do item do Menu

Passo 2- Criando a tabela no banco de dados, antes de popula-la

No arquivo STARTUP.CS, acrescente em services,addIdentity a parte de código relativo a

//Seting the Account Login page
            services.ConfigureApplicationCookie(options =>
Se ao compilar o Visual Stdio reclamar que não consegue apagar um diretório na pasta OBJ da aplicação, apague manualmente e recompile novamente,
ARQUIVO STARTUP.CS - acrescente metodo services.ConfigureApplicationCooki
services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
  
  
            //Password Strength Setting
            services.Configure<IdentityOptions>(options =>
            {
                // Password settings
                options.Password.RequireDigit = true;
                options.Password.RequiredLength = 8;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = true;
                options.Password.RequireLowercase = false;
                options.Password.RequiredUniqueChars = 6;
  
                // Lockout settings
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                options.Lockout.MaxFailedAccessAttempts = 10;
                options.Lockout.AllowedForNewUsers = true;
  
                // User settings
                options.User.RequireUniqueEmail = true;
            });
// COPIE A PARTIR DAQUI  
            //Seting the Account Login page
            services.ConfigureApplicationCookie(options =>
            {
                // Cookie settings
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                options.LoginPath = "/Account/Login"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
                options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
                options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
                options.SlidingExpiration = true;
            });
  //COPIE ATÉ AQUI

Agora vamos criar o modelo com a classe MenuMaster, na pasta Models:

modelo com a classe MenuMaster, na pasta Models:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace DiagnosticoCultura.Models
{
public class MenuMaster
    {
        [Key]
				[Display(Name = "Id do Menu (chave)")]
        public int MenuIdentity { get; set; }


			  [Display(Name = "Identidade do menu")]
        public string MenuID { get; set; }

				[Display(Name = "Nome de display do Menu")]
        public string MenuName { get; set; }

				[Display(Name = "MenuID do Menu Pai (quando existir)")]
        public string Parent_MenuID { get; set; }

  			[Display(Name = "Papel (Role) em que o menu está permitido")]
        public string User_Roll { get; set; }

	  		[Display(Name = "Nome da ação DENTRO DO CONTROLLER")]
        public string MenuFileName { get; set; }
       
			 [Display(Name = "Nome do CONTROLLER")]
		  	public string MenuURL { get; set; }

			  [Display(Name = "Mostra Menu (Y-N)")]
        public string USE_YN { get; set; }
       
  			//alternativa: colocar no controle yourModel.DataCadastro = DateTime.Now;
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
        [Display(Name = "Data de Criação do Menu")]
			  public DateTime CreatedDate { get; set; }

 				public MenuMaster()
    		{
        CreatedDate = DateTime.Now;
   	 		}
    }
}

Passo 3 – Gerando a tabela MASTERMENU no nosso database

Recompile a aplicação para ver se até aqui não deu qualquer erro. O resultado deve ser:

========== Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========

No Solution Explorer clique na pasta Controllers e com o botão da direita selecione ADD->New Scaffolded Item. Escolha MVC e à direita escolha MVC Controllers with Views, using Entity Framework. Clique no botão ADD.

Em Model Class escolher  o modelo MenuMaster , que ai aparecer como MenuMaster (DiagnosticoCultura.Models) . Clique no botão ADD.

Agora vamos Rodar a miração na console PMC:

add-migration mastermenu

e depois

update-database

Se compilar o programa e digitar https://localhost:44387/MenuMasters você verá que está tudo pronto para cadastrar os menus.

Passo 4 – Criando classes de interface

Agora é hora de criarmos uma interface com um método chamado GetMenuMaster() e outro método chamado GetMenuMaster (String UserRole).

Implementaremos essa interface em nosso serviço para obter todos os detalhes do menu da tabela e também outro método para obter o menu considerando o papel (ROLE) do usuário.

Para criar a interface, adicione uma nova classe à sua pasta de modelos e nomeie a classe como “IMenuMasterService”. Vamos mudar a classe para uma interface, pois vamos criar uma interface para implementar em nosso serviço

interface de modelos de menus ARQUIVO IMenuMasterService.CS PASTA mODELS
public interface IMenuMasterService
    {
        IEnumerable<MenuMaster> GetMenuMaster();
        IEnumerable<MenuMaster> GetMenuMaster(String UserRole);
     }

Passo 5: Criação do Serviço de Menus:

Agora vamos adicionar uma nova pasta de serviços de classe (abrir uma pasta raiz chamada Services) e nomear a classe como “MenuMasterService“.

Nesta classe, estaremos implementando nossa interface IMenuMasterService.

Sabemos que, se implementarmos a interface, devemos declarar o método de interface em nossa classe. Neste serviço, usamos o método de interface e retornamos a lista com detalhes do Menu e também retornamos os detalhes do Menu por função do usuário. Depois estaremos injetando isso diretamente em nossa página de visualização.

code snipet Criacaoo do Servco de Menus:folder SERVICER arquivo MenuMasterService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using DiagnosticoCultura.Data;
using DiagnosticoCultura.Models;



namespace DiagnosticoCultura.Services
{

    public class MenuMasterService : IMenuMasterService
    {
        private readonly ApplicationDbContext _context;
        public MenuMasterService(ApplicationDbContext dbContext)
        {
            _context = dbContext;
        }
        public IEnumerable<MenuMaster> GetMenuMaster()
        {
            return _context.MenuMaster.AsEnumerable();

        }

        public IEnumerable<MenuMaster> GetMenuMaster(string UserRole)
        {
            var result = _context.MenuMaster.Where(m => m.User_Roll == UserRole).ToList();
            return result;
        }
    }
}

Passo 6: Registrando o serviço

Precisamos registrar nosso serviço criado no contêiner. Abra o Startup.cs do seu projeto para adicionar o serviço ao contêiner.

Na classe Startup.cs, encontre o método denominado ConfigureServices e adicione seu serviço “MenuMasterService” como abaixo.

Registrando o servico no startup.cs (acrescentar MenuMasterService em ConfigureServices)
// adicionar using DiagnosticoCultura.Services;
//no topo do arquivo startup.cs

services.AddTransient<MenuMasterService, MenuMasterService>();

Passo 7: Injetando o serviço de menus na página _Layout.cshtml

Agora, é muito mais simples e fácil, já que podemos injetar diretamente o serviço em nossa página de visualização e vincular todo o resultado à nossa página de visualização.

Para injetar o Serviço em nossa Visualização, aqui estaremos usando nossa página _Layout.cshtml existente.

Como vamos exibir o menu no topo do nosso site e usá-lo em todas as nossas páginas, aqui usamos a página _Layout.cshtml para vincular os resultados do menu como um menu baseado no usuário logado.

Aqui primeiro verificamos se o usuário está Autenticado em nosso site. Se o usuário estiver logado, obteremos os detalhes do papel do usuário conectado e vincularemos o menu com base nas funções do usuário.

Aqui no exemplo estamos vinculando 2 nível do menu como Menu Principal e Submenu.

Em nosso resultado de tabela, verificamos todos os Parenut_MenuID = ”*”, já que estaremos exibindo o menu principal com o parent_MenuID como “*” e no próximo loop interno, exibimos o submenu apropriado para o menu principal.

IMPORTANTE> Faça um backup do _Layout.cshtml ANTES de alterar qualquer coisa, Se 

mudancas na pagina _Layout,cshtml (pasta ViewsShared) - veja o que deve ser acrescentado e onde
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Diagnóstico de Cultura</title>


    <!-- Essential JS 2 Base's material theme (Dependency Styles) -->
    <link href="https://cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" type="text/css" />

    <!-- Essential JS 2 Button's material theme (Control Styles) -->
    <link href="https://cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" type="text/css" />

    <!-- Essential JS 2 Base's global script (Dependency Script) -->
    <script src="https://cdn.syncfusion.com/ej2/ej2-base/dist/global/ej2-base.min.js" type="text/javascript"></script>

    <!-- Essential JS 2 Button's global script (Control Script) -->
    <script src="https://cdn.syncfusion.com/ej2/ej2-buttons/dist/global/ej2-buttons.min.js" type="text/javascript"></script>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
              crossorigin="anonymous"
              integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" />
    </environment>
    <!-- Syncfusion Essential JS 2 Styles -->
    <link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/material.css" />

    <!-- Syncfusion Essential JS 2 Scripts -->
    <script src="https://cdn.syncfusion.com/ej2/dist/ej2.min.js"></script>
    <link rel="stylesheet" href="~/css/site.css" />
  

</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Diagnóstico de Cultura</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
               
              <div class="navbar-collapse collapse">
 <ul class="nav navbar-nav">
   <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
 @if (User.Identity.IsAuthenticated)
        {
            var UserRoles = "";
            if (@User.IsInRole("Admin"))
            {
                UserRoles = "Admin";
            }
            else
            {
                UserRoles = "Manager";
            }
  
                @if (menus.GetMenuMaster(@UserRoles).Any())
                {
                @if (menus.GetMenuMaster(@UserRoles).Any())
                {
                @foreach (var menuNames in menus.GetMenuMaster(@UserRoles).Where(n => n.Parent_MenuID == "*"))
                {
                        <li>
                            <a asp-area="" asp-controller=@menuNames.MenuURL asp-action=@menuNames.MenuFileName>@menuNames.MenuName</a>
                            <ul class="sub-menu">
                                @foreach (var subMenu in menus.GetMenuMaster(@UserRoles).Where(n => n.Parent_MenuID == @menuNames.MenuID))
                                  {
                                    <li>
                                        <a asp-area="" asp-controller=@subMenu.MenuURL asp-action=@subMenu.MenuFileName>@subMenu.MenuName</a>
                                    </li>
                                   }
                            </ul>
                            </li>
                }
                }
                }
            }
  </ul>
              
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <partial name="_CookieConsentPartial" />
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>


    <footer class="border-top footer text-muted">
        <div class="container">
            © 2019 - Diagnóstico de Cultura - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>

    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=">
        </script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o">
        </script>
    </environment>
    <script src="~/js/site.js" asp-append-version="true"></script>
    
    @RenderSection("Scripts", required: false)
    
    <ejs-scripts></ejs-scripts>
</body>
</html>

Obrigado pela sua leitura. Continue visitando este blog e compartilhe artigos em sua rede de relacionamento. Por favor, se quiser, registre sugestões e comentários ao final da página.