Angular
9 - CRUD com ASP .NET Core WEB API 3.1
![]() |
Vamos implementar uma aplicação ASP .NET Core Web API usando a versão 3.1 e realizar as operações CRUD usando o Angular 9. |
Neste tutorial vamos iniciar criando um projeto exemplo para tratar dos detalhes de pagamentos de um cartão de Crédito.
![]() |
recursos usados:
Criando uma WEB API com ASP .NET Core
Abra o
VS 2019
Community e crie um novo projeto( File-> New Project )
;
Selecione o template ASP .NET Core Web Application, e, Informe o nome Api_Cartao;
A seguir selecione .NET Core e ASP .NET Core 3.1 e marque o template API e as configurações conforme a figura abaixo:
Clicando no botão Create teremos o projeto criado e pronto para ser ajustado onde vamos remover os arquivos que não iremos usar no projeto.
Configurando o banco de dados
Vamos criar um banco de dados para este projeto e vamos usar o Entity Framework Core para realizar as operações com o banco de dados.
Para isso vamos instalar os seguintes pacotes Nuget para referênciar as referências do Entity FrameworkCore:
Repita os procedimentos abaixo para cada pacote:
Crie na raiz do projeto a pasta Models e nesta pasta crie a classe Pagamento que vai representar a entidade do nosso modelo de domínio anêmico:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ApiCartao.Models
{
public class Pagamento
{
public int PagamentoId { get; set; }
[Required]
[Column(TypeName = "nvarchar(100)")]
public string NomeTitular { get; set; }
[Required]
[Column(TypeName = "varchar(16)")]
public string NumeroCartao { get; set; }
[Required]
[Column(TypeName = "varchar(5)")]
public string DataExpiracao { get; set; }
[Required]
[Column(TypeName = "varchar(3)")]
public string CVV { get; set; }
}
}
|
Na mesma pasta Models crie o arquivo AppDbContext que representa o nosso arquivo de contexto que vai herdar de DbContext e permitir a comunicação entre o EF Core o banco de dados:
using Microsoft.EntityFrameworkCore;
namespace ApiCartao.Models
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) :
base(options)
{ }
public DbSet<Pagamento> Pagamentos { get; set; }
}
}
|
A classe
AppDbContext decide o que deve ser adicionado ao
banco de dados físico durante a migração do banco de dados. Para isso,
adicionamos a propriedade DbSet à classe
Pagamento, assim, após a migração, a tabela
Pagamentos e a base de dados serão criados no SQL
Server.
No parâmetro options do construtor da classe, temos
que passar qual o provedor do banco de dados
(SQL Server, MySQL, PostgreSQL, etc) vamos usar e informar a
string de conexão.
Para isso, usaremos a injeção de dependência no arquivo Startup do projeto fazendo o registro do serviço:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(optionns =>
optionns.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers();
}
|
Podemos ainda habilitar o CORS incluindo no método ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(optionns =>
optionns.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed((host) => true)
.AllowCredentials());
});
services.AddControllers();
}
|
Isso é importante para permitir as requisições que serão feitas pela aplicação Angular do endereço localhost:4200.
E no método Configure incluir o código a seguir:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseStaticFiles();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
|
Precisamos ainda definir no arquivo appsettings.json a string de conexão definida com o nome DefaultConnection:
{ "ConnectionStrings": { "DefaultConnection": "Data Source=Macoratti;Initial Catalog=PagamentoCartaoDB;Integrated Security=True" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" } |
Pronto, já podemos aplicar o Migrations emitindo os comandos abaixo na janela do Package Manager Console :
add-migration inicial
update-database
Ao final teremos o banco de dados PagamentoCartaoDB.mdf e a tabela Pagamentos criados no SQL Server.
Criando a API para as operações CRUD
Vamos criar o controlador PagamentosController na pasta Controllers do projeto usando o Scaffold.
Para isso clique com o botão direito do mouse sobre a pasta Controllers e clique em Add->Controller;
A seguir selecione a opção : API Controller with actions, using Entity Framework e clique em Add;
A seguir informe os dados na janela Add API Controller with.. conforme abaixo
Clique no botão Add para criar o controlador PagamentosController:
using ApiCartao.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ApiCartao.Controllers
{
[Route("api/[controller]")]
[Produces("application/json")]
[ApiController]
public class PagamentosController : ControllerBase
{
private readonly AppDbContext _context;
public PagamentosController(AppDbContext context)
{
_context = context;
}
// GET: api/Pagamentos
[HttpGet]
public async Task<ActionResult<IEnumerable<Pagamento>>> GetPagamentos()
{
return await _context.Pagamentos.ToListAsync();
}
// GET: api/Pagamentos/5
[HttpGet("{id}")]
public async Task<ActionResult<Pagamento>> GetPagamento(int id)
{
var pagamento = await _context.Pagamentos.FindAsync(id);
if (pagamento == null)
{
return NotFound();
}
return pagamento;
}
// PUT: api/Pagamentos/5
[HttpPut("{id}")]
public async Task<IActionResult> PutPagamento(int id, Pagamento pagamento)
{
if (id != pagamento.PagamentoId)
{
return BadRequest();
}
_context.Entry(pagamento).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!PagamentoExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/Pagamentos
[HttpPost]
public async Task<ActionResult<Pagamento>> PostPagamento(Pagamento pagamento)
{
_context.Pagamentos.Add(pagamento);
await _context.SaveChangesAsync();
return CreatedAtAction("GetPagamento", new { id = pagamento.PagamentoId }, pagamento);
}
// DELETE: api/Pagamentos/5
[HttpDelete("{id}")]
public async Task<ActionResult<Pagamento>> DeletePagamento(int id)
{
var pagamento = await _context.Pagamentos.FindAsync(id);
if (pagamento == null)
{
return NotFound();
}
_context.Pagamentos.Remove(pagamento);
await _context.SaveChangesAsync();
return pagamento;
}
private bool PagamentoExists(int id)
{
return _context.Pagamentos.Any(e => e.PagamentoId == id);
}
}
}
|
Acima temos o código gerado pelo Scaffolding onde vemos os métodos da Web POST, GET, PUT e DELETE para operações de criação, recuperação, atualização e exclusão, respectivamente.
Aqui estamos injetando uma instância do nosso contexto AppDbContext no construtor para poder realizar as operações com as entidades e persistir no banco de dados via EF Core.
Estamos seguindo as práticas para as API REST e estamos forçando a nossa API a retornar JSON. Assim não precisamos alterar os métodos HTTP gerados e podemos inclusive testar as operações CRUD usando um software como o Postman.
Ao final temos os
seguintes endpoints definidos:
GET /api/Pagamentos/
- Recupera todos os registros
GET /api/Pagamentos/id
- Recupera um registro com o ID fornecido
POST /api/Pagamentos/
- Criar um novo registro
PUT /api/Pagamentos/id
- Atualiza um registro com o ID fornecido
DELETE /api/Pagamentos/id - Exclui um
registro com o ID fornecido
Nota: Um endpoint é, de forma simplificada, a URL que monta o caminho para fazer a requisição;
Encerramos aqui a parte da criação da API.
Apenas para fazer um teste para o GET executando o projeto teremos o resultado a seguir:
Se você quiser melhorar o código desacoplando o controlador do EF Core basta criar um repositório, definir uma interface a sua implementação e a seguir injetar a instância do repositório no controlador ao invés de usar diretamente o contexto.
Isso eu vou deixar como um exercício para você, afinal é um conceito que todo o desenvolvedor deve ter.
Na próxima parte do artigo vamos criar a aplicação Angular.
Pegue o projeto
aqui :
ApiCartao.zip (sem as
referências)
"Porque o reino
de Deus não é comida nem bebida, mas justiça, e paz, e alegria no Espírito
Santo."
Romanos 14:17
Referências: