Angular 7 - Consumindo Web API ASP .NET MVC - I


  Hoje veremos como consumir uma Web API ASP .NET MVC 5 em uma aplicação Angular 7.

Neste tutorial passo a passo, vamos criar uma WEB API ASP .NET MVC 5 e a seguir criar uma aplicação Angular 7 para consumir a WEB API realizando as operações CRUD.

Vou usar um banco de dados do SQL Server e uma API ASP .NET MVC 5 para fornecer conectividade entre o banco de dados e o aplicativo front-end. No lado da interface do usuário, vamos usar o tema Material Angular para criar uma experiência de usuário rica, interativa e independente de dispositivo.

Vamos realizar essa tarefa em duas etapas:

  1. Criação da aplicação WEB API ASP .NET MVC 5;
  2. Criação da aplicação Angular;

Para criar a Web API podemos usar o Visual Studio 2019 Community ou o Visual Studio Code e para criar a aplicação Angular vamos usar o Angular CLI 7.0 e o Angular Material versão 7.

Vamos usar o banco de dados Estudo e a tabela Clientes com a estrutura e dados exibidos a seguir:

A seguir temos o script SQL para gerar a tabela Clientes:

USE [Estudo]
GO
CREATE TABLE [dbo].[Clientes](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Nome] [nvarchar](80) NOT NULL,
	[Endereco] [nvarchar](150) NULL,
	[Telefone] [nvarchar](80) NULL,
	[Email] [nvarchar](250) NULL,
	[Cidade] [nvarchar](150) NULL,
);

Vamos então iniciar criando a WEB API.

Criando uma Web API ASP .NET MVC

Vou usar o Visual Studio Community 2019 para criar a Web API.

E para tornar o exemplo mais simples vamos criar uma API que gerencia informações de Clientes onde teremos como modelo de domínio uma entidade Cliente.

Vamos criar uma aplicação ASP .NET Web Application(.NET Framework) usando o template API no Visual Studio 2019 Community chamada Mvc5_Angular7Crud;

Abra o VS 2019 Community e selecione : Create a new Project

Selecionando em Language : C#, Platform: Windows e em Project Type: web podemos selecionar o template ASP .NET Web Application(.NET Framework):

A seguir vamos informar o nome do projeto Mvc5_Angular7Crud sua localização e nome da solução.

Finalmente selecione o template Web API conforme mostrado a seguir:

Marque a opção para configurar HTTP e não vamos usar Autenticação, ao final clique em Create.

Ao final teremos um projeto Web API que iremos usar para definir nossas APIs.

Vamos incluir no projeto o pacote do EntityFramework via menu Tools:

Estamos usando a versão 6.2.0 do EntityFramework.

Definindo o modelo de domínio e o contexto

Vamos criar na pasta Models do projeto a classe Cliente que sera o nosso modelo de domínio.

A classe Cliente:

using System.ComponentModel.DataAnnotations.Schema;
namespace Mvc5_Angular7Crud.Models
{
    [Table("Clientes")]
    public class Cliente
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public string Endereco { get; set; }
        public string Telefone { get; set; }
        public string Email { get; set; }
        public string Cidade { get; set; }        
    }
}

A seguir vamos definir na pasta Models a classe de contexto AppDbContext que herda de DbContext.

using System.Data.Entity;
namespace Mvc5_Angular7Crud.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext() : base("name=AppDbContext")
        { }
        public virtual DbSet<Cliente> Clientes { get; set; }
    }
}

Nesta classe definimos o nome do contexto e mapeamos a entidade Cliente para a tabela Clientes.

Agora vamos definir no arquivo Web.config do projeto a string de conexão e usando o nome AppDbContext que é o mesmo nome do nosso contexto:

 ...
 <connectionStrings>
    <add name="AppDbContext" connectionString="Data Source=.\;Initial Catalog=Estudo;Integrated Security=True" providerName="System.Data.SqlClient" />
  </connectionStrings>
 <system.webServer>
...

Criando o controlador ClientesController

Vamos agora criar o controlador que representa a nossa API para poder gerenciar os clientes.

Clique com o botão direito do mouse sobre a pasta Controllers e selecione a opção Add Controller;

Na janela Add Scaffold escolha a opção Web API 2 Controller with actions using Entity Framework;

Na janela a seguir informe os dados conforme mostrado na figura abaixo:

Após clicar no botão Add, nosso controlador ClientesController será criado na pasta Controllers.

Teremos o controlador gerado com os métodos Action prontos para realizar as operações CRUD na tabela Clientes.

Uma abordagem mais robusta seria criar um repositório para centrar a lógica de acesso aos dados, mas como nossa API é bem simples vamos usar as funcionalidades CRUD acessando diretamente o EF Core.

Após fazer alguns ajustes no código gerado pelo Scaffold temos abaixo o código do controlador:

using Mvc5_Angular7Crud.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Http.Description;
namespace Mvc5_Angular7Crud.Controllers
{
    [RoutePrefix("api/clientes")]
    public class ClientesController : ApiController
    {
        private AppDbContext db = new AppDbContext();
        // GET: api/clientes    
        [HttpGet]
        [Route("todos")]
        public IQueryable<Cliente> GetClientes()
        {
            return db.Clientes;
        }
        // GET: api/Clientes/5
        [ResponseType(typeof(Cliente))]
        [HttpGet]
        [Route("{id}")]
        public IHttpActionResult GetCliente(int id)
        {
            Cliente cliente = db.Clientes.Find(id);
            if (cliente == null)
            {
                return NotFound();
            }
            return Ok(cliente);
        }
        // POST: api/Clientes
        [ResponseType(typeof(Cliente))]
        [HttpPost]
        [Route("incluir")]
        public IHttpActionResult PostCliente(Cliente cliente)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            db.Clientes.Add(cliente);
            db.SaveChanges();
            return CreatedAtRoute("DefaultApi", new { id = cliente.Id }, cliente);
        }
        // PUT: api/Clientes/5
        [ResponseType(typeof(void))]
        [HttpPut]
        [Route("alterar")]
        public IHttpActionResult PutCliente(int id, Cliente cliente)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            if (id != cliente.Id)
            {
                return BadRequest();
            }
            db.Entry(cliente).State = EntityState.Modified;
            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ClienteExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return StatusCode(HttpStatusCode.NoContent);
        }
        private bool ClienteExists(int id)
        {
            return db.Clientes.Count(e => e.Id == id) > 0;
        }
        // DELETE: api/Clientes/5
        [ResponseType(typeof(Cliente))]
        [HttpDelete]
        [Route("excluir")]
        public IHttpActionResult DeleteCliente(int id)
        {
            Cliente cliente = db.Clientes.Find(id);
            if (cliente == null)
            {
                return NotFound();
            }
            db.Clientes.Remove(cliente);
            db.SaveChanges();
            return Ok(cliente);
        }
    }
}

Cabe destacar no código acima o seguinte:

- Estamos definindo o roteamento para acessar a API usando :   [RoutePrefix("api/clientes")]

- Em cada método Action usamos o atributo [HttpGet],[HttpPost],[HttpPut] e [HttpDelete] e o atributo Route[] onde definimos um template de rota para cada método Action:

Apenas para testar, executando o projeto, e acessando a url: https://localhost:16434/api/clientes/todos teremos o seguinte resultado:

Poderíamos realizar os testes das operações CRUD usando o Postman como eu mostrei neste artigo:
Testando as operações CRUD da Web API com Postman

Antes de concluir precisamos alterar o código do método Register do arquivo WebApiConfig na pasta App_Start para habilitar o CORS e também para forçar a resposta no formato JSON.

using System.Web.Http;
using System.Web.Http.Cors;
namespace Mvc5_Angular7Crud
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Habilita o CORS
            var cors = new EnableCorsAttribute("*", "*", "*");//origins,headers,methods   
            config.EnableCors(cors);
            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
             // força o response no formato JSON 
            var formatters = GlobalConfiguration.Configuration.Formatters;
            formatters.Remove(formatters.XmlFormatter);
        }
    }
}

O Cross-Origin Resource Sharing ou 'compartilhamento de recursos de origem cruzada' cujo acrônimo é CORS é um padrão W3C sendo uma especificação de uma tecnologia de navegadores que define meios para um servidor permitir que seus recursos sejam acessados por uma página web de um domínio diferente.

Temos que habilitar o CORS no projeto WEB API para poder enviar uma requisição a partir da aplicação Angular que vai estar em outro domínio.

Temos assim nossa API pronta para ser consumida e é isso que iremos fazer na segunda parte do artigo.

Pegue o projeto da WEB API aqui : Mvc5_Angular7Crud.zip

"O Senhor é o meu rochedo, e o meu lugar forte, e o meu libertador; o meu Deus, a minha fortaleza, em quem confio; o meu escudo, a força da minha salvação, e o meu alto refúgio."
Salmos 18:2

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 ?

Referências:


José Carlos Macoratti