ASP .NET Core 5 - CRUD com EF Core 5 usando imagens - II
Hoje vamos iniciar a criação de um projeto web usando a ASP .NET Core 5.0 onde vamos realizar um CRUD com a ajuda do EF Core 5.0 e também mostrar como tratar imagens. |
Continuando a primeira parte do artigo vamos definir as view models para customizar a exibição dos dados em nosso projeto.
Criando as ViewModels
Vamos criar uma pasta chamada ViewModels no projeto e a seguir vamos criar as seguintes classes nesta pasta:
1- UploadImagemViewModel
using Microsoft.AspNetCore.Http;
using System.ComponentModel.DataAnnotations;
namespace Palestras.ViewModels
{
public class UploadImagemViewModel
{
[Required]
[Display(Name = "Foto")]
public IFormFile PalestranteFoto { get; set; }
}
}
|
Aqui estamos usando a interface IFormFile que representa o arquivo enviado com o request. Vamos usar este recurso para fazer o upload da imagem do palestrante.
2- EditImagemViewModel
public class EditImagemViewModel : UploadImagemViewModel
{
public int Id { get; set; }
public string ImagemExistente { get; set; }
}
|
Esta classe permite tratar as imagens já existentes que foram enviadas.
3- PalestranteViewModel
using System;
using System.ComponentModel.DataAnnotations;
namespace Palestras.ViewModels
{
public class PalestranteViewModel : EditImagemViewModel
{
[Required]
public string Nome { get; set; }
[Required]
[Display(Name = "Qualificação")]
public string Qualificacao { get; set; }
[Required]
[Display(Name = "Experiência")]
public int Experiencia { get; set; }
[Required]
[DataType(DataType.Date)]
[Display(Name = "Data")]
public DateTime DataPalestra { get; set; }
[Required]
[DataType(DataType.Time)]
[Display(Name = "Hora")]
public DateTime HoraPalestra { get; set; }
[Required]
public string Local { get; set; }
}
}
|
Esta viewmodel temos as informações do palestrante que iremos usar para realizar a edição dos dados.
Criamos assim 3 ViewModels definindo as propriedades que iremos usar para gerenciar a exibição das informações do palestrante.
Ajustando o código do controlador PalestrantesController
Agora com base nas ViewModels criadas vamos ajustar o código que foi gerado pelo Scaffold no controlador PalestrantesController.
Vamos incluir no controlador uma instância da interface IWebHostEnvironment além da instância do contexto que foi incluida pelo Scaffold:
public class PalestrantesController : Controller
{
private readonly AppDbContext _context;
private readonly IWebHostEnvironment webHostEnvironment;
public PalestrantesController(AppDbContext context, IWebHostEnvironment hostEnvironment)
{
_context = context;
webHostEnvironment = hostEnvironment;
}
...
}
|
Após isso vamos criar o método ProcessaUploadedFile() que vai gerenciar o Upload dos arquivos salvando os arquivos enviados na pasta Uploads dentro da pasta wwwroot :
private string ProcessaUploadedFile(PalestranteViewModel model) { string nomeArquivoImagem = null; if (model.PalestranteFoto != null)
{
string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "Uploads");
nomeArquivoImagem = Guid.NewGuid().ToString() + "_" + model.PalestranteFoto.FileName;
string filePath = Path.Combine(uploadsFolder, nomeArquivoImagem);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
model.PalestranteFoto.CopyTo(fileStream);
}
}
return nomeArquivoImagem;
}
|
A seguir temos os métodos Action com a alteração pertinente para tratar a imagem do usuário e usar as view models criadas:
1- Método Details
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var palestrante = await _context.Palestrantes
.FirstOrDefaultAsync(m => m.Id == id);
var palestranteViewModel = new PalestranteViewModel()
{
Id = palestrante.Id,
Nome = palestrante.Nome,
Qualificacao = palestrante.Qualificacao,
Experiencia = palestrante.Experiencia,
DataPalestra = palestrante.DataPalestra,
HoraPalestra = palestrante.HoraPalestra,
Local = palestrante.Local,
ImagemExistente = palestrante.Foto
};
if (palestrante == null)
{
return NotFound();
}
return View(palestrante);
}
|
2- Método Create (Post)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(PalestranteViewModel model)
{
if (ModelState.IsValid)
{
string nomeArquivoImagem = ProcessaUploadedFile(model);
Palestrante palestrante = new Palestrante
{
Nome = model.Nome,
Qualificacao = model.Qualificacao,
Experiencia = model.Experiencia,
DataPalestra = model.DataPalestra,
HoraPalestra = model.HoraPalestra,
Local = model.Local,
Foto = nomeArquivoImagem
};
_context.Add(palestrante);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(model);
}
|
3- Método Edit (Get)
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var palestrante = await _context.Palestrantes.FindAsync(id);
var palestranteViewModel = new PalestranteViewModel()
{
Id = palestrante.Id,
Nome = palestrante.Nome,
Qualificacao = palestrante.Qualificacao,
Experiencia = palestrante.Experiencia,
DataPalestra = palestrante.DataPalestra,
HoraPalestra = palestrante.HoraPalestra,
Local = palestrante.Local,
ImagemExistente = palestrante.Foto
};
if (palestrante == null)
{
return NotFound();
}
return View(palestranteViewModel);
}
|
4- Método Edit (Post)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, PalestranteViewModel model)
{
if (ModelState.IsValid)
{
try
{
var palestrante = await _context.Palestrantes.FindAsync(model.Id);
palestrante.Nome = model.Nome;
palestrante.Qualificacao = model.Qualificacao;
palestrante.Experiencia = model.Experiencia;
palestrante.DataPalestra = model.DataPalestra;
palestrante.HoraPalestra = model.HoraPalestra;
palestrante.Local = model.Local;
if (model.PalestranteFoto != null)
{
if (model.ImagemExistente != null)
{
string filePath = Path.Combine(webHostEnvironment.WebRootPath, "Uploads", model.ImagemExistente);
System.IO.File.Delete(filePath);
}
palestrante.Foto = ProcessaUploadedFile(model);
}
_context.Update(palestrante);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
throw;
}
return RedirectToAction(nameof(Index));
}
return View();
}
|
5- Método Delete
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var palestrante = await _context.Palestrantes
.FirstOrDefaultAsync(m => m.Id == id);
var palestranteViewModel = new PalestranteViewModel()
{
Id = palestrante.Id,
Nome = palestrante.Nome,
Qualificacao = palestrante.Qualificacao,
Experiencia = palestrante.Experiencia,
DataPalestra = palestrante.DataPalestra,
HoraPalestra = palestrante.HoraPalestra,
Local = palestrante.Local,
ImagemExistente = palestrante.Foto
};
if (palestrante == null)
{
return NotFound();
}
return View(palestranteViewModel);
}
|
6- Método DeleteConfirmed
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int? id)
{
var palestrante = await _context.Palestrantes.FindAsync(id);
var CurrentImage = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\uploads", palestrante.Foto);
_context.Palestrantes.Remove(palestrante);
if (await _context.SaveChangesAsync() > 0)
{
if (System.IO.File.Exists(CurrentImage))
{
System.IO.File.Delete(CurrentImage);
}
}
return RedirectToAction(nameof(Index));
}
|
Pronto agora já temos tudo pronto e teremos que fazer alguns ajustes nas views geradas na pasta /Views/Palestrantes que você pode ver no arquivo anexo contendo o projeto.
Executando o projeto teremos o resultado a seguir:
Pegue o código do projeto aqui: EventosNet2.zip (sem as referências)
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 Core - Gerenciador de Despesas ...
ASP .NET Core - Acessando dados com Entity .
ASP.NET Core Web API - Tratamento de erros
ASP .NET Core MVC - Tratamento de exceções - II
ASP .NET Core - CRUD usando Blazor e Entity ..
ASP .NET Core Blazor - Macoratti.net
Blazor - Vale a pena usar o Blazor
ASP .NET Core 2 - MiniCurso Básico
ASP .NET Core - Implementando a segurança .
Curso ASP .NET Core - Macoratti.net
ASP .NET Core 3.1 - Conteinerizando uma ...