ASP.NET Core MVC - CRUD usando leiaute AdminLTE - I


 Neste artigo vamos realizar um CRUD básico em uma aplicação ASP .NET Core MVC usando o leiaute do template AdminLTE.

O template AdminLTE é um modelo pronto para a execução de projetos ASP.NET MVC de alta qualidade sendo que ele também inclui outros plugins úteis.

No exemplo deste artigo vou usar o Visual Studio 2019 Community Preview8 e a ASP .NET Core 3.0 Preview.

Vamos então realizar as seguintes tarefas :

  1. Baixar o pacote do template AdminLTE neste link: https://github.com/ColorlibHQ/AdminLTE
  2. Criar um projeto ASP .NET Core MVC vazio;
  3. Ajustar o projeto para usar o template manualmente;
  4. Criar o modelo de domínio Paciente;
  5. Criar o controlador PacientesController e respectivas views;
  6. Realizar o CRUD na tabela Pacientes do SQL Server;

Abaixo vemos a tabela Pacientes e os dados existentes:

O Script SQL para gerar a tabela Pacientes é o seguinte:

USE [Cadastro]
GO
CREATE TABLE [dbo].[Pacientes](
	[PacienteId] [int] IDENTITY(1,1) NOT NULL,
	[Nome] [nvarchar](100) NOT NULL,
	[Email] [nvarchar](150) NOT NULL,
	[Telefone] [nvarchar](50) NOT NULL,
	[Clinica] [nvarchar](50) NULL,
	[DataCadastro] [datetime] NULL
 )

Nosso objetivo será criar o seguinte leiaute:

Então ao trabalho...

Recursos usados:

Criando o projeto ASP .NET Core MVC

Abra o Visual Studio 2019 Community Preview e clique em New Project:

No menu File selecione Add -> New Project;

A seguir selecione :

Escolha o template ASP .NET Core Web Application e clique em Next :

A seguir informe o nome AspnAdminLte_Crud e clique em Create.

Selecione .NET Core e ASP .NET Core 3.0 e o template Empty e clique em Create:

Nosso projeto ASP .NET Core MVC foi criado e agora vamos ajustá-lo.

Vamos abrir o arquivo Startup.cs e realizar os seguintes procedimentos:

  1. habilitar o serviço MVC
  2. definir a utilização dos arquivos estáticos
  3. criar um roteamento padrão para o controlador Home e o método Action Index

Abaixo temos o código definido nos métodos ConfigureServices para habilitar o serviço MVC e no método Configure onde definimos a utilização dos arquivos estáticos e criarmos um roteamento padrão:

  public class Startup
  {
        public void ConfigureServices(IServiceCollection services)
        {
            //habilita serviço MVC
            services.AddControllersWithViews();
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }            
            //habilita o uso de arquivos estáticos
            app.UseStaticFiles();
            //habilita o roteamento
            app.UseRouting();
            //Define um roteamento padrão
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    "default", "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Note que o código é um pouco diferente da versão anterior. Para detalhes veja a documentação neste link.

A seguir crie 3 pastas no projeto:

  1. Controllers
  2. Models
  3. Views

A estrutura do projeto deve ficar assim:

Criando e configurando o modelo de domínio e o contexto

Na pasta Models vamos criar a classe Paciente que representa o nosso modelo de domínio:

using System;
using System.ComponentModel.DataAnnotations;
namespace AspnAdminLte_Crud.Models
{
    public class Paciente
    {
        public int PacienteId { get; set; }
        [Required(ErrorMessage = "O nome do paciente é obrigatório", AllowEmptyStrings = false)]
        public string Nome { get; set; }
        [Required(ErrorMessage = "O email do paciente é obrigatório", AllowEmptyStrings = false)]
        public string Email { get; set; }
        [Required(ErrorMessage = "O telefone do paciente é obrigatório", AllowEmptyStrings = false)]
        public string Telefone { get; set; }
        [Required(ErrorMessage = "Informe a clinica do paciente", AllowEmptyStrings = false)]
        public string Clinica { get; set; }
        [DataType(DataType.Date)]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
        [Display(Name = "Data do cadastro")]
        [Required(ErrorMessage = "Informe a data do cadastro")]
        public DateTime DataCadastro { get; set; }
    }
}

Estamos definindo as propriedades para realizar o mapeamento ORM usando o EF Core e também usamos o recurso Data Annotations para realizar a validação do modelo.

Ainda na pasta Models crie a classe AppDbContext que herda de DbContext e representa o nosso contexto definindo o mapeamento ORM:

using Microsoft.EntityFrameworkCore;
namespace AspnAdminLte_Crud.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {}
        public DbSet<Paciente> Pacientes { get; set; }
    }
}

Vamos registrar o contexto como um serviço no método ConfigureServices da classe Startup do projeto:

 public class Startup
    {
        public IConfiguration Configuration { get; }
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddDbContext<AppDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddControllersWithViews();
        }

 

Fizemos a injeção via DI da interface IConfiguration e a seguir registramos o contexto - AppDbContext - como um serviço definindo o provedor do banco de dados usado - UseSqlServer, e a string de conexão identificada por 'DefaultConnection'.

No arquivo appsettings.json vamos definir um seção com este nome e definir a string de conexão com o nosso banco de dados:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=MACORATTI;Initial Catalog=Cadastro;Integrated Security=True;
Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;
MultiSubnetFailover=False"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Na pasta Views vamos criar dois arquivos:

  1. _ViewStart.cshtml - Aqui vamos definir o arquivo de layout que vamos usar no projeto;
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
  1. _ViewImports.cshtml - Vamos incluir uma referência para poder usar as TagHelpers no projeto;
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Com essas configurações já podemos acessar os dados da nossa tabela no SQL Server e agora vamos criar o controlador e as views.

Usando o pacote do template AdminLTE

Após baixar o pacote, descompacte o pacote AdminLTE em uma pasta local. Você deve ver os seguintes arquivos:

Copie apenas as pasta dist e bower_components para a pasta wwwroot do projeto ASP .NET Core MVC.

Dentro da pasta dist/img você deve colocar as imagens que deseja usar no projeto.

Criando o controlador e definindo o leiaute

Crie um controlador HomeController na pasta Controllers e o método Action Index com o código abaixo:

using Microsoft.AspNetCore.Mvc;
namespace AspnAdminLte_Crud.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

A seguir dentro da pasta Shared crie um arquivo _Layout.cshtml e inclua o código abaixo:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <title>Admin Panel</title>
      <!-- Tell the browser to be responsive to screen width -->
      <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
      <link rel="stylesheet" href="~/bower_components/bootstrap/dist/css/bootstrap.min.css">
      <!-- Font Awesome -->
      <link rel="stylesheet" href="~/bower_components/font-awesome/css/font-awesome.min.css">
      <!-- Ionicons -->
      <link rel="stylesheet" href="~/bower_components/Ionicons/css/ionicons.min.css">
      <!-- Theme style -->
      <link rel="stylesheet" href="~/dist/css/AdminLTE.min.css">
      <link rel="stylesheet" href="~/dist/css/skins/skin-blue.min.css">
      <!-- Google Font -->
      <link rel="stylesheet"
       href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">
    </head>
    <body class="hold-transition skin-blue sidebar-mini">
    <div class="wrapper">
      <!-- Main Header -->
      <header class="main-header">
        <!-- Logo -->
        <a href="index2.html" class="logo">
          <!-- mini logo for sidebar mini 50x50 pixels -->
          <span class="logo-mini"><b>AP</b>T</span>
          <!-- logo for regular state and mobile devices -->
          <span class="logo-lg"><b>AdminPanel</b>Tutorial</span>
        </a>
        <!-- Header Navbar -->
        <nav class="navbar navbar-static-top" role="navigation">
          <!-- Sidebar toggle button-->
          <a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
            <span class="sr-only">Toggle navigation</span>
          </a>
          <!-- Navbar Right Menu -->
          <div class="navbar-custom-menu">
            <ul class="nav navbar-nav">
              <!-- User Account Menu -->
              <li class="dropdown user user-menu">
                <!-- Menu Toggle Button -->
                <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                  <!-- The user image in the navbar-->
                  <img src="~/dist/img/maco_oval.jpg" class="user-image" alt="Usuário">
                  <!-- hidden-xs hides the username on small devices so only the image appears. -->
                  <span class="hidden-xs">Macoratti</span>
                </a>
                <ul class="dropdown-menu">
                  <!-- The user image in the menu -->
                  <li class="user-header">
                    <img src="~/dist/img/maco_oval.jpg" class="img-circle" alt="User Image">
                    <p>
                      Macoratti - Macoratti.net
                      <small>Membro desde Nov. 2002</small>
                    </p>
                  </li>
                  <!-- Menu Body -->
                  <li class="user-body">
                    <div class="row">
                      <div class="col-xs-4 text-center">
                        <a href="#">Conta</a>
                      </div>
                    </div>
                    <!-- /.row -->
                  </li>
                  <!-- Menu Footer-->
                  <li class="user-footer">
                    <div class="pull-left">
                      <a href="#" class="btn btn-default btn-flat">Perfil</a>
                    </div>
                    <div class="pull-right">
                      <a href="#" class="btn btn-default btn-flat">Sign out</a>
                    </div>
                  </li>
                </ul>
              </li>
            </ul>
          </div>
        </nav>
      </header>
      <!-- Left side column. contains the logo and sidebar -->
      <aside class="main-sidebar">
        <!-- sidebar: style can be found in sidebar.less -->
        <section class="sidebar">
          <!-- Sidebar user panel (optional) -->
          <div class="user-panel">
            <div class="pull-left image">
              <img src="~/dist/img/maco_oval.jpg" class="img-circle" alt="Imagem do usuário">
            </div>
            <div class="pull-left info">
              <p>Macoratti</p>
              <!-- Status -->
              <a href="#"><i class="fa fa-circle text-success"></i> Online</a>
            </div>
          </div>
          <!-- formulário de busca (Opcional) -->
          <form action="#" method="get" class="sidebar-form">
            <div class="input-group">
              <input type="text" name="q" class="form-control" placeholder="Procurar...">
              <span class="input-group-btn">
                 <button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
                 </button>
                </span>
            </div>
          </form>
          <!-- /.search form -->
          <!-- Sidebar Menu -->
          @Html.Partial("_MainMenu")
          <!-- /.sidebar-menu -->
        </section>
        <!-- /.sidebar -->
      </aside>
      <!-- Content Wrapper. Contains page content -->
      <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        @RenderBody()
        <!-- /.content -->
      </div>
      <!-- /.content-wrapper -->
      <!-- Main Footer -->
      <footer class="main-footer">
        <!-- Default to the left -->
        <strong>Copyright &copy; 2018 <a href="https://www.macoratti.net">Macoratti.net</a>.</strong> 
All rights reserved.
      </footer>
    </div>
    <!-- ./wrapper -->
    <!-- REQUIRED JS SCRIPTS -->
    <!-- jQuery 3 -->
    <script src="~/bower_components/jquery/dist/jquery.min.js"></script>
    <!-- Bootstrap 3.3.7 -->
    <script src="~/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- AdminLTE App -->
    <script src="~/dist/js/adminlte.min.js"></script>
    </body>
    </html>

Agora crie o arquivo _MainMenu.cshtml na pasta Shared e inclua o código a seguir:

<ul class="sidebar-menu" data-widget="tree">
    <li class="header">Menu</li>
    <!-- Optionally, you can add icons to the links -->
    <li class="treeview">
        <a href="#">
            <i class="fa fa-user"></i> <span>Pacientes</span>
            <span class="pull-right-container">
                <i class="fa fa-angle-left pull-right"></i>
            </span>
        </a>
        <ul class="treeview-menu">
            <li><a href="/Pacientes/Create">Incluir Novo</a></li>
            <li><a href="/Pacientes">Exibir Todos</a></li>
        </ul>
    </li>
</ul>

A estrutur do projeto deve estar da seguinte maneira:



Dentro da pasta Views crie outra pasta chamada Home e dentro desta pasta crie o arquivo Index.cshtml incluindo o código a seguir:

<section class="content-header">
    <h1>
        Atendimento 
        <small>inicial</small>
    </h1>
</section>
<!-- Main content -->
<section class="content container-fluid">
    <img src="~/dist/img/cadpaci.jpg" class="img-fluid" width="700" height="466" />
</section>

Pronto !

Executando o projeto neste momento iremos obter o seguinte resultado:

Pronto !!!

Configuramos o template para exibir em nossa aplicação ASP .NET Core MVC um painel com imagens, menus e uma caixa de busca.

Naturalmente temos apenas a camada de apresentação, na próxima parte do artigo vamos criar o nosso controlador PacientesController e acessar e gerenciar os dados dos pacientes.

"Porque Deus não nos destinou para a ira, mas para a aquisição da salvação, por nosso Senhor Jesus Cristo,
Que morreu por nós, para que, quer vigiemos, quer durmamos, vivamos juntamente com ele."

1 Tessalonicenses 5:9,10

     DVDs com programas para estudo e Cursos de VB .NET e C#

       Visite a loja on-line para ver todos os cursos :  Loja do Macoratti.net
 

Referências:


José Carlos Macoratti