Neste artigo vou mostrar como utilizar o padrão ViewModel em aplicações ASP .NET Core MVC. |
O padrão Model View ViewModel (MVVM) foi introduzido por John Gosmann em 2005 e é uma especialização do padrão de projeto Presentation Model (PM) que foi introduzido em 2004 por Martin Fowler.
Estruturalmente, uma aplicação que usa o padrão MVVM consiste basicamente em três componentes principais: o Modelo, a Visão(View) e a ViewModel.
Em uma aplicação ASP .NET MVC a ViewModel contém a lógica de interface do usuário, os comandos, os eventos, e uma referência para o modelo e não tema a responsabilidade de atualizar os dados da interface do usuário.
Assim a ViewModel representa apenas os dados que queremos exibir na View e pode ser composta de um ou mais Models.
Vamos supor que temos uma aplicação onde temos uma entidade Cliente e uma entidade Pedido e vamos precisar exibir em uma view informações de Cliente e de Pedido. Para poder fazer isso podemos criar uma ViewModel chamada ClienteViewModel e selecionar as propriedades que desejamos exibir de ambas as entidades (Cliente + Pedido).
Para mostrar um exemplo prático usando esse cenário vamos criar uma aplicação ASP .NET MVC usando o Entity Framework e o SQL Server onde teremos um banco de dados Vendas.mdf e as tabelas Clientes e Pedidos cuja estrutura é exibida a seguir:
Vamos precisar conhecer a string de conexão deste banco de dados no SQL Server. Para o meu exemplo a string de conexão é : Data Source=.\;Initial Catalog=Vendas;Integrated Security=True
Você pode obter a string de conexão abrindo o Server Explorer e a seguir abrir uma conexão com o banco Vendas e depois pressionar F4 e ver na janela de propriedades a string de conexão.
Para acompanhar este artigo você precisa ter instalado o Visual Studio Community 2017 com os seguintes workloads e recursos instalados:
Se você não tem nenhuma noção sobre como funciona o padrão MVC e sua implementação ASP .NET sugiro que leia esses artigos :
Criando uma nova aplicação ASP .NET MVC
Abra no VS 2017 e no menu File clique em New Project;
A seguir selecione o template Visual C# -> Web e marque ASP .NET Core Web Application (.NET Framework);
Informe o nome Aspn_ViewModel e clique no botão OK;
Na próxima janela escolha a versão ASP .NET Core 1.1 e marque o template Web Application sem autenticação e clique no botão OK;
Teremos o projeto ASP .NET MVC criado contendo a estrutura básica, conforme figura abaixo, que será o nosso ponto de partida.
Instalando o Entity Framework Core 1.1
O
Entity Framework Core (EF Core) é uma versão leve, extensível e
multiplataforma do Entity Framework. O EF Core introduz muitas melhorias e novos
recursos quando comparado com o EF6.x. O EF Core mantém a experiência do
desenvolvedor do EF6.x e a maioria das APIs de alto nível permanecem as mesmas,
então o EF Core vai te parecer muito familiar se você conhece o Entity Framework
6.x.
Para
instalar o Entity Framework em nosso projeto vamos usar a opção do menu
Tools-> Nuget Package Manager -> Package Manage Console.
Você deve instalar o pacote para o provedor do banco de dados EF Core que você deseja acessar. Os provedores atualmente disponíveis podem ser vistos neste link: Database Providers
Neste artigo vamos instalar o provider para o SQL Server.
Abra a janela do Console do Gerenciador de Pacotes clicando no menu Tools-> Nuget Package Manager -> Package Manage Console.
A seguir digite o seguinte comando : Install-Package Microsoft.EntityFrameworkCore.SqlServer
Para concluir vamos instalar o Microsoft.EntityFrameworkCore.Design para ter acesso às ferramentas de design para o SqlServer.
Na janela do Console digite o comando : Install-Package Microsoft.EntityFrameworkCore.Design
Criando o Modelo a partir do banco de dados
Agora que temos o suporte ao EF Core vamos criar o nosso modelo de entidades com base no banco de dados existente.
No menu Tools clique em Package Manager Console e a seguir na janela do console digite o comando:
Scaffold-DbContext
"Data
Source=.\;Initial Catalog=Vendas;Integrated
Security=True"
Microsoft.EntityFrameworkCore.SqlServer
Nesta instrução temos :
O comando: Scaffold-DbContext
A string de conexão do banco de dados : "Data Source=.\;Initial Catalog=Vendas;Integrated Security=True"
O nome do provedor usado : Microsoft.EntityFrameworkCore.SqlServer
Na figura abaixo vemos o comando após a sua execução gerar as classe Clientes.cs , Pedidos.cs e VendasContext :
O processo de engenharia reversa criou as classes das entidades e um contexto derivado baseado no esquema do banco de dados existente. As classes de entidade são objetos C# simples que representam os dados que você estará consultando e salvando, no nosso exemplo, são as informações de clientes e pedidos.
Registrando o contexto com injeção de dependência
A ASP.NET Core implementa a injeção de dependência por padrão. Os serviços (como o contexto de banco de dados do EF) são registrados com injeção de dependência durante a inicialização do aplicativo. Componentes que requerem esses serviços (como controladores MVC) fornecem esses serviços através de parâmetros do construtor.
Para que os controladores MVC da nossa aplicação utilizem o VendasContext, vamos registrar o contexto como um serviço.
Para registrar o nosso contexto VendasContext como um serviço, abra o arquivo Startup.cs e adicione as linhas realçadas em azul ao método ConfigureServices:
using Microsoft.EntityFrameworkCore; ... .... // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var connection = @"Data Source =.\; Initial Catalog = Vendas; Integrated Security = True"; services.AddDbContext<VendasContext>(options => options.UseSqlServer(connection)); // Add framework services.
services.AddMvc();
}
.... |
Nota: Um aplicativo real geralmente colocaria a string de conexão em um arquivo de configuração. Por uma questão de simplicidade, estamos definindo-a via código.
Criando a ViewModel : ClienteViewModel
Agora sim vamos aplicar o padrão ViewModel pois desejamos exibir em uma view as informações de clientes e pedidos. Vamos então criar uma pasta ViewModel no projeto para organizar o código.
Selecione o projeto e no menu Project clique em New Folder e informe o nome ViewModel.
Selecione esta pasta e no menu Project clique em Add Class e informe o nome ClienteViewModel. A seguir inclua o código abaixo na classe ClienteViewModel:
using System;
namespace Aspn_ViewModel.ViewModel
{
public class ClienteViewModel
{
public int ClienteViewModelId { get; set; }
public string Nome { get; set; } // Cliente
public string Endereco { get; set; } // Cliente
public string Email { get; set; } // Cliente
public DateTime? DataPedido { get; set; } // Pedido
public Nullable<decimal> PrecoPedido { get; set; } // Pedido
}
}
|
Dessa forma criamos a nossa ViewModel contendo informação das entidades Cliente e Pedido para serem exibidas em uma View.
Criando o Controller : ClientePedidosController
A criação automática dos métodos Actions para realizar o CRUD e as Views é conhecida como Scaffolding. O Scaffolding irá criar automaticamente os métodos Action e as Views, e, quando você precisar personalizar o código gerado, você pode usar classes parciais ou você regenera o código quando as houver alterações.
Vamos iniciar criando um controlador em nosso projeto. Clique com o botão direito do mouse sobre a pasta Controllers, e a seguir clique em Add -> Controller;
Na janela Add MVC Dependencies selecione a opção - Minimal Dependencies e clique no botão Add;
O VS 2017 vai adicionar as dependências necessárias para montar o controller.
Após isso repita o procedimento e clique com o botão direito do mouse sobre a pasta Controllers, e a seguir clique em Add -> Controller;
Na janela Add Scaffold selecione a opção : MVC Controller - Empty
Clique no botão Add.
Agora na janela Add Controller informe o nome : ClientePedidosController
Ao clicar no botão Add, o mecanismo de Scaffolding do Visual Studio irá criar um arquivo ClientePedidosController.cs, na pasta Controllers.
Vamos abrir o arquivo ClientePedidoController e incluir o código abaixo na Action Index:
using Aspn_ViewModel.ViewModel;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
namespace Aspn_ViewModel.Controllers
{
public class ClientePedidosController : Controller
{
public IActionResult Index()
{
//cria uma instância do contexto
VendasContext db = new VendasContext();
//Para tratar as informações de clientes e pedidos
List<ClienteViewModel> listaClientesVM = new List<ClienteViewModel>();
//consulta os dados do banco de dados
//fazendo a junção da duas tabelas
//e armazenando as informações em listaClientes
var listaClientes = (from Cli in db.Clientes
join Ped in db.Pedidos on Cli.ClienteId equals Ped.ClienteId
select new { Cli.Nome, Cli.Email, Cli.Endereco,
Ped.DataPedido, Ped.PrecoPedido }).ToList();
//percorre a lista de clientes e preenche
//a ViewModel com os dados que serão exibidos na view
foreach (var item in listaClientes)
{
ClienteViewModel cliVM = new ClienteViewModel(); //ViewModel
cliVM.Nome = item.Nome;
cliVM.Email = item.Email;
cliVM.Endereco = item.Endereco;
cliVM.DataPedido = item.DataPedido;
cliVM.PrecoPedido = item.PrecoPedido;
listaClientesVM.Add(cliVM);
}
//Retorna as informações para View
return View(listaClientesVM);
}
}
}
|
O código já esta comentado e basicamente retorna as informações de clientes e pedidos da ViewModel para a View.
Criando a View Index para exibir informações a partir da ViewModel
Vamos agora criar a View Index para exibir as informações da ViewModel.
Clique com o botão direito sobre o método Action Index() no controlador ClientePedidosController e a seguir clique em Add View.
A seguir informe os dados conforme a figura abaixo:
Clicando no botão Add teremos a view Index.cshtml criada na pasta Views/ClientePedidos com o seguinte código:
@model IEnumerable<Aspn_ViewModel.ViewModel.ClienteViewModel>
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>@Html.DisplayNameFor(model => model.Nome)</th>
<th>@Html.DisplayNameFor(model => model.Endereco)</th>
<th>@Html.DisplayNameFor(model => model.Email)</th>
<th>@Html.DisplayNameFor(model => model.DataPedido)</th>
<th>@Html.DisplayNameFor(model => model.PrecoPedido)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>@Html.DisplayFor(modelItem => item.Nome)</td>
<td>@Html.DisplayFor(modelItem => item.Endereco)</td>
<td>@Html.DisplayFor(modelItem => item.Email)</td>
<td>@Html.DisplayFor(modelItem => item.DataPedido)</td>
<td>@Html.DisplayFor(modelItem => item.PrecoPedido)</td>
<td>
<a asp-action="Edit" asp-route-id="@item.ClienteViewModelId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ClienteViewModelId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ClienteViewModelId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
|
Executando o projeto e navegando para ClientePedidos iremos obter o seguinte resultado:
Dessa forma vemos a exibição na View Index das informações de clientes e pedidos obtidas a partir da View Model - ClienteViewModel - criada para esta finalidade.
Isso posto temos que :
- A sua view não depende
mais do Model mas da ViewModel;
- Você pode agrupar informações de diversos Models em uma única classe: a
ViewModel;
- Voce não terá que alterar uma classe do Model para atender as necessidades de
uma View;
- Você pode fazer mudanças na sua ViewModel sem afetar o modelo de domínio;
Pegue o projeto aqui :
Aspn_ViewModel.zip
(sem as referências)
(Disse Jesus) Todo o que o Pai me dá virá a mim; e o
que vem a mim de maneira nenhuma o lançarei fora.
João 6:37
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: