ASP .NET Core - Criando uma app Básica com EFCore, Web API e Angular 2 - II

 Neste artigo vou mostrar como criar uma aplicação ASP .NET Core integrando o Angular 2 para criar uma aplicação Básica que consome uma Web API e exibe um formulário com controles dropdwon, radiobutton, checkbox e textbox.

Neste artigo vamos criar a nossa Web API ASP .NET Core e utiilizar o AutoMapper para mapear as classes do domínio e resolver o problema da referência circular entre as entidades Modelo e Marca. (Veja o artigo anterior neste link)


O problema do relacionamento entre as entidades Modelo e Marca : Usando o AutoMapper

Vamos recordar a definição das entidades Modelo e Marca usadas no projeto:

 public class Marca
    {
        public int Id {get; set; }
        public string Nome {get;set;}

        public ICollection<Modelo> Modelos {get;set;}
        public Marca()
        {
            Modelos = new Collection<Modelo>();
        }
    }
    public class Modelo
    {
        public int Id { get; set; }
        public string Nome { get; set; }

        public Marca Marca { get; set; }
        public int MarcaId { get; set; }
    }

 

Marca Modelo

Na definição da classe Modelo optamos por incluir uma propriedade MarcaId como chave estrangeira de forma a facilitar a atualização de um objeto Modelo no futuro, pois para associar um Modelo com uma Marca basta usar a propriedade MarcaId sem ter a necessidade de localizar uma marca no banco de dados pelo seu id.

Ocorre que essa abordagem vai resultar em um problema quando formos serializar os dados no formato JSON causando um loop ou referência circular. Para resolver esse problema teremos que criar classes que reflitam o nosso modelo de domínio, sem usar o recurso da chave estrangeira, para evitar o problema da referência circular, e, que possamos expor para o cliente via serialização JSON.

Primeiro vamos criar classes que reflitam o nosso  modelo de domínio e que podemos expor para o cliente via serialização. Vamos criar uma pasta chamada Resources dentro da pasta Controllers e a seguir vamos criar as classes MarcaResource, ModeloResource e AcessorioResource  conforme o código abaixo:

 public class MarcaResource
    {
        public int Id {get; set; }
        public string Nome {get;set;}

        public ICollection<Modelo> Modelos {get;set;}
        public Marca()
        {
            Modelos = new Collection<Modelo>();
        }
    }
    public class ModeloResource
    {
        public int Id { get; set; }
        public string Nome { get; set; }
    }

 

 public class AcessorioResource
    {
        public int Id { get; set; }
        public string Nome { get; set; }
    }

 

MarcaResource ModeloResource AcessorioResource

Instalando e registrando o AutoMapper

O AutoMapper é uma biblioteca construída para resolver um problema complexo :  livrar-se de um código que mapeou um objeto para outro.

Para instalar o AutoMapper no projeto abra uma janela do Package Manager Console, via menu Tools, e digite o comando : Install-Package AutoMapper

Vamos instalar também o pacote  AutoMapper.Extensions.Microsoft.DependencyInjection via nuget.

A seguir vamos abrir o arquivo Startup.cs e registrar o AutoMapper no método ConfigureServices:

 public void ConfigureServices(IServiceCollection services)
 {
      services.AddAutoMapper();

     services.AddDbContext<AlfaDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ConexaoAlfa")));
      // Add framework services.
      services.AddMvc();
}

Mapeando o modelo de entidades com o AutoMapper

Agora que já criamos as classes que representam o nosso modelo de domínio e temos o AutoMapper instalado e registrado vamos realizar o mapeamento entre as classes do modelo de domínio e as classes criadas na pasta Resources que representam o nosso domínio sem o relacionamento usando a chave estrangeira.

Crie uma pasta chamada Mapping no projeto e defina uma classe chamada MappingProfile contendo o seguinte código :

using Alfa.Controllers.Resources;
using Alfa.Models;
using AutoMapper;
namespace Alfa.Mapping
{
    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<Marca, MarcaResource>();
            CreateMap<Modelo, ModeloResource>();
            CreateMap<Acessorio, AcessorioResource>();
        }
    }
}

Neste código estamos mapeando as 3 classes que representam o nosso modelo de entidades(Marca,Modelo e Acessorio) para as classes que iremos expor via serialização JSON ao cliente.

Criando a Web API para expor marcas, modelos e acessórios

Agora vamos criar dois controladores na pasta Controllers onde vamos expor as marcas, modelos e acessórios como um serviço da nossa Web API.

  1. MarcasControllers -  Retorna as marcas e respectivos modelos;
  2. AcessoriosControllers - Permite acessar e retornar os acessórios dos veículos;

1 - MarcasControllers

using Alfa.Controllers.Resources;
using Alfa.Models;
using Alfa.Persistencia;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Alfa.Controllers
{
    public class MarcasController : Controller
    {
        private readonly AlfaDbContext context;
        private readonly IMapper mapper;
        public MarcasController(AlfaDbContext context, IMapper mapper)
        {
            this.context = context;
            this.mapper = mapper;
        }
        [HttpGet("/api/marcas")]
        public async Task<IEnumerable<MarcaResource>> GetMarcas()
        {
            var marcas = await context.Marcas.Include(m => m.Modelos).ToListAsync();
            return mapper.Map<List<Marca>, List<MarcaResource>>(marcas);
        }
    }
}

2 - AcessoriosControllers

using Alfa.Controllers.Resources;
using Alfa.Models;
using Alfa.Persistencia;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace Alfa.Controllers
{
    public class AcessoriosController : Controller
    {
        private readonly AlfaDbContext context;
        private readonly IMapper mapper;
        public AcessoriosController(AlfaDbContext context, IMapper mapper)
        {
            this.context = context;
            this.mapper = mapper;
        }
        [HttpGet("/api/acessorios")]
        public async Task<IEnumerable<AcessorioResource>> GetAcessorios()
        {
            var acessorios = await context.Acessorios.ToListAsync();
            return mapper.Map<List<Acessorio>, List<AcessorioResource>>(acessorios);
        }
    }
}

Dessa forma temos as seguintes rotas definidas em nossa Web API:

  • api/marcas - retorna as marcas e respectivos modelos;
  • api/acessorios - retorna os acessórios;

Neste momento já temos o serviço da Web API pronto para ser consumido e vamos definir um formulário que vai exibir essas informações usando o Angular 2.

Na próxima parte do artigo vamos criar iniciar a criação da interface do usuário definindo componentes usando o Angular CLI e o BootStrap.

O anjo do Senhor acampa-se ao redor dos que o temem, e os livra.
Salmos 34:7

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:


José Carlos Macoratti