ASP .NET
Core 3.1 - Implementando a Paginação e o Filtro de dados
![]() |
Neste artigo vou mostrar como podemos implementar a paginação e o filtro de dados em uma aplicação ASP .NET Core MVC na versão 3.1. |
Existem muitas abordagens que podemos usar para implementar a paginação e o filtro de dados em uma aplicação ASP .NET Core MVC.
![]() |
Podemos fazer a implementação usando apenas os recursos da ASP .NET Core por nossa conta via código C#. Essa abordagem é a mais trabalhosa mas tem a vantagem de não depender de pacotes de terceiros.
A outra abordagem é usar um pacote de terceiros, é mais fácil e rápido mas como desvantagem seu projeto passa a depender de um dependência externa. Nada contra, mas se o pacote for gratuito lembre-se que o desenvolvedor pode não atualizar o pacote na mesma velocidade que o framework é atualizado e isso pode quebrar sua aplicação.
Neste artigo eu vou usar o pacote ReflectionIT.Mvc.Paging que é distribuído via Nuget e que a documentação (muito fraca por sinal) pode ser consultada no GitHub: https://github.com/sonnemaf/ReflectionIT.Mvc.Paging
O objetivo é mostrar mais uma opção para realizar a paginação e o filtro de dados.
Assim vou começar criando uma aplicação ASP .NET Core MVC com .NET Core 3.1 e a seguir vou implementar a paginação e o filtro de dados usando os recursos deste pacote.
recursos usados:
Criando o projeto inicial no VS 2019
Abra o VS 2019 Community e crie um novo projeto via menu File-> New Project;
Selecione o template ASP .NET Core Web Application, e, Informe o nome da solução IdentityTotal (ou outro nome a seu gosto) e o nome do projeto FuncionariosWeb.
A seguir selecione .NET Core e ASP .NET Core 3.1 e marque o template Web Application e as configurações conforme figura abaixo:
Observe que não vamos definir agora a autenticação em nosso projeto vamos fazer isso depois.
Depois que o projeto foi criado, precisamos adicionar a referência aos seguintes pacotes:
Noata: Para instalar use o comando Install-Package <nome> -version 3.1.3
Esses pacotes são necessários para realizarmos o acesso ao banco de dados SQL Server e aplicarmos o Migrations ao modelo de domínio e assim gerar o banco de dados e as tabelas.
Definindo o modelo de domínio
Na pasta Models do projeto crie a classe Funcionario e a enumeração Departamento:
using System.ComponentModel.DataAnnotations;
namespace FuncionariosWeb.Models
{
public class Funcionario
{
public int FuncionarioId { get; set; }
[Required, MaxLength(80, ErrorMessage = "Nome não pode exceder 80 caracteres")]
public string Nome { get; set; }
[RegularExpression(@"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
ErrorMessage = "Email com formato inválido")]
[Required]
public string Email { get; set; }
public Departamento? Departamento { get; set; }
}
}
|
Enumeração Departamento:
namespace FuncionariosWeb.Models
{
public enum Departamento
{
TI,
RH,
Contabilidade,
Marketing,
Vendas
}
}
|
Criando e registrando o contexto e aplicando o Migrations
Agora crie uma pasta Context no projeto e nesta pasta crie o arquivo AppDbContext:
using FuncionariosWeb.Models;
using Microsoft.EntityFrameworkCore;
namespace FuncionariosWeb.Context
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{ }
public DbSet<Funcionario> Funcionarios { get; set; }
}
}
|
No método ConfigureServices do arquivo Startup registre o serviço do contexto:
...
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(
options => options.
UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
}
...
|
E no arquivo appsettings.json inclua a string de conexão com o banco de dados usando sua instância local:
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=Macoratti;Initial Catalog=FuncionariosDBWeb;Integrated Security=True"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
|
Para criar o banco de dados e a tabela com as configurações definidas abra uma janela do Package Manager Console e digite o comando:
add-migration Inicial
Isso vai gerar o script de migração na pasta Migrations que será criada no projeto. Não havendo nenhum erro então emita o comando :
update-database
Isso vai criar o banco de dados e as tabelas no SQL Server.
Nota: Para alimentar a tabela com dados você pode usar a classe de Contexto - AppDbContext e definir a sobrescrita do método OnModelCreating :
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Funcionario>().HasData(
new Funcionario
{
FuncionarioId = 1,
Nome = "Macoratti",
Departamento = Departamento.TI,
Email = "macoratti@yahoo.com"
});
}
|
Nota: Eu vou incluir mais alguns dados para realizar os testes.
Criando o controlador
Agora vamos criar o controlador para gerenciar as informações dos funcionários e fazer o CRUD.
Clique com o botão direito do mouse sobre a pasta Controllers e a seguir clique em Add->Controller;
A seguir escolha a opção MVC Controller with views, using Entity Framework e clique em Add;
Na janela a seguir informe o modelo Funcionario, o data context AppDbContext e informe o nome FuncionariosController e clique em Add:
Ao final será criado o controlador e as views.
Ajustando a view _Layout.cshtml para ter um link para exibir o acessso aos funcionários temos:
..
<div
class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse"> |
Agora é só alegria...
Executando o projeto teremos:
Pronto, já temos nossa aplicação ASP .NET Core MVC e agora vamos implementar a paginação e filtro de dados.
Implementando a Paginação,a ordenação e o Filtro de dados
Vamos incluir o pacote ReflectionIT.Mvc.Paging no projeto. Podemos fazer isso via janela do Package Manager Console digitando: Install-Package ReflextionIT,Mvc.Paging -version 4.0.0 ou via menu Tools do VS 2019.
A seguir vamos definir o serviço de paginação no arquivo Startup no método ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(
options => options.
UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
services.AddPaging(options => {
options.ViewName = "Bootstrap4";
options.PageParameterName = "pageindex";
});
}
|
Após isso vamos alterar o método Action usado para gerar a View onde vamos aplicar a paginação.
Vamos abrir o controlador FuncionariosController e alterar o método Action Index conforme abaixo:
public async Task<IActionResult> Index(string filter, int pageindex = 1, string sort = "Nome") { var resultado = _context.Funcionarios.AsNoTracking() .AsQueryable(); if (!string.IsNullOrWhiteSpace(filter)) { resultado = resultado.Where(p => p.Nome.Contains(filter)); } var model = await PagingList.CreateAsync(resultado, 5, pageindex, sort, "Nome");
model.RouteValue = new RouteValueDictionary { { "filter", filter } };
return View(model);
}
|
Neste código definimos o filtro, a paginação e a ordenação pela propriedade Nome.
Alteramos a consulta incluindo um AsQueryable() para que possamos aplicar uma cláusula Where à consulta quando o filtro não for null.
Esta consulta é usada para criar o PagingList onde definimos o tamanho da página com igual a 5 , definindo a ordenação pela coluna Nome.
A seguir definimos a rota de dados para gerar a URL onde criamos uma instância de RouteValueDictionary que representa uma coleção de pares chave/valor que não diferenciam maiúsculas de minúsculas.
Agora precisamos ajustar a view Index.cshtml conforme a seguir:
@model ReflectionIT.Mvc.Paging.PagingList<FuncionariosWeb.Models.Funcionario>
@{
ViewData["Title"] = "Index";
}
<p>
<a asp-action="Create">Criar Novo</a>
</p>
<form method="get" class="form-inline">
<input name="filter" class="form-control" placeholder="filtro"
value="@Model.RouteValue["Filter"]" />
<button type="submit" class="btn btn-info">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span> Procurar
</button>
</form>
Total funcionários : @Model.TotalRecordCount
<div>
<vc:pager paging-list="@Model"></vc:pager>
</div>
<table class="table">
<thead>
<tr>
<th>@Html.SortableHeaderFor(model => model.Nome, "Nome")</th>
<th>@Html.DisplayNameFor(model => model.Email)</th>
<th>@Html.DisplayNameFor(model => model.Departamento)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.Nome)</td>
<td>@Html.DisplayFor(modelItem => item.Email) </td>
<td>@Html.DisplayFor(modelItem => item.Departamento)</td>
<td>
<a asp-action="Edit" asp-route-id="@item.FuncionarioId">Edita</a> |
<a asp-action="Details" asp-route-id="@item.FuncionarioId">Detalhe</a> |
<a asp-action="Delete" asp-route-id="@item.FuncionarioId">Deleta</a>
</td>
</tr>
}
</tbody>
</table>
|
Alteramos o tipo do model para ReflectionIT.Mvc.Paging.PagingList e definimos o paginador usando um View Component que vai permitir navegar pelos registros.
Criamos o formulário para definir a caixa de texto e o botão para filtrar os dados com base no filtro passando via parãmetro.
No cabeçalho que exibe a coluna Nome usamos o SortableHeaderFor para destacar a coluna pela qual estamos ordenando.
Para concluir temos que incluir no arquivo _ViewImports.cshtml a referência ao namespace e à tagHelper:
@using FuncionariosWeb
@using ReflectionIT.Mvc.Paging
@using FuncionariosWeb.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, ReflectionIT.Mvc.Paging |
Executando o projeto teremos o resultado a seguir:
O projeto completo aqui:
IdentityTotal_Paginacao.zip (sem as referências)
"Foge também das paixões da mocidade; e segue a
justiça, a fé, o amor, e a paz com os que, com um coração puro, invocam
o Senhor."
2 Timóteo 2:22
Referências:
ASP .NET Core - Implementando a segurança com ..
ASP.NET Core MVC - Criando um Dashboard ...
C# - Gerando QRCode - Macoratti
ASP .NET - Gerando QRCode com a API do Google
ASP .NET - Gerando QRCode com a API do Google
ASP .NET Core - Iniciando com o Blazor - Macoratti
ASP .NET Core - CRUD usando Blazor e Entity ...