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

 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 dropdownlist, radiobutton, checkbox e textbox.

O principal objetivo deste artigo é mostrar como integrar o Angular 2 a uma aplicação ASP .NET Core e consumir o serviço de uma Web API para uma aplicação básica.

Vamos criar uma aplicação básica que gerencia informações sobre Veículos, e, para tornar o contexto o mais simples possível, vamos tratar informações de Marcas, Modelos e Acessórios.

Para criar o projeto ASP .NET Core com Angular 2 vamos usar o Yeoman, depois vamos definir o nosso Modelo de domínio, incluir o Entity Framework Core, criar o banco de dados usando o Migrations, criar a Web API de serviços e ao final integrar o Angular 2 para consumir o serviço e exibir as informações no cliente em um formulário com recursos do Bootstrap.

Durante o desenvolvimento da aplicação iremos usar o terminal de comandos, o Visual Studio 2017 Community e o VS Code para editar o código do projeto.

São muitas etapas e vou procurar ser o mais objetivo possível para não estender demais o artigo.

Recursos usados:

Criando o projeto ASP .NET Core usando o Yeoman

Nota: Atualmente o projeto pode ser criado usando os templates do Visual Studio.

Se você não não conhece o Yeoman leia este artigo : NET - Apresentando o Yeoman - Macoratti

Como o Yeoman é distribuido como um pacote NPM vamos precisar possuir os seguintes recursos instalados para usar o Yeoman.

Abra um terminal de comandos e crie uma pasta para o projeto.

Para o artigo eu vou criar uma pasta chamada Alfa :  md alfa

A seguir entre na pasta criada e digite o comando para criar o projeto usando o Yeoman : yo aspnetcore-spa

Selecion a opção para usar o Angular como framework e tecle Enter:

Informe No para incluir os testes unitários e tecle Enter para confirmar o nome do projeto como alfa.

O projeto será criado e as dependências serão instaladas na pasta node_modules.

Se desejar, você pode executar o projeto digitando no terminal de comando: dotnet run  (a aplicação vai estar atendendo em http://localhost:5000)

Nota: Você pode também abrir o projeto no VS Code, abrir uma janela de terminal e digitar o mesmo comando para executar a aplicação.

Espiando a estrutura do projeto criado

Vamos abrir o projeto criado no VS Code e examinar sua estrutura.

Estando no terminal de comando digite : Code .

O projeto será aberto no VS Code e veremos a seguinte estrutura:

Temos as seguintes pastas no projeto:

- ClienteApp  - local onde teremos o código do lado do cliente definido pelo Angular 2;

- Controllers - local onde são criados os controladores Asp .Net Core. Aqui iremos criar nossa Web API;

- Views - local onde são criadas as views Asp .Net Core;

- node_modules - contém das dependências para o Angular 2;

- wwwroot - pasta onde são colocados os arquivos públicos e estáticos da aplicação : ícones, imagens, fontes, etc.;

Além disso temos os seguintes arquivos que foram gerados:

  • Startup.cs - classe que processa o pipeline de requisições que trata todas as requisições feitas para a aplicação;
  • Program.cs - Contém o ponto de entrada principal do aplicativo;
  • Alfa.csproj - O arquivo de projeto para a ASP .NET Core Web API;
  • appsettings.json - Arquivo de configuração do aplicativo de base do ambiente;
  • tsconfig.json - configuração para o TypeScript;

Incluindo uma referência ao Entity Framework Core

Vamos adicionar o suporte ao EF Core em nosso projeto e instalar o provedor do banco de dados que vamos usar. No exemplo deste artigo vamos instalar o provedor SQL Server : Microsoft.EntityFrameworkCore.SqlServer.

Para instalar esse pacote abra uma janela do Package Manager Console via menu Tools e digite o comando : Install-Package Microsoft.EntityFrameworkCore.SqlServer

Este pacote e suas dependências ( Microsoft.EntityFrameworkCore e Microsoft.EntityFrameworkCore.Relational ) fornece o suporte em tempo de execução ao EF.(Mais adiante iremos instalar outro pacote para a migração)

Nota:  O EF para no .NET Core não possui todas as funcionalidades do EF 6. (lazy loading não esta suportado ainda)

Vamos instalar também os seguintes pacotes usando o comando Install-Package :

  • Microsoft.EntityFrameworkCore.Tools no projeto para ter acesso ao Migrations :
  • Microsoft.EntityFrameworkCore.SqlServer.Design - para poder executar os comandos dotnet no projeto;

Criando o modelo de domínio da aplicação

Abra o projeto no VS 2017 Community e crie uma pasta chamada Models no projeto.

A seguir vamos definir 4 classes nesta pasta Models que irão representar o nosso modelo de domínio e o arquivo de contexto da aplicação.

  • classe Marca - representa as Marcas dos veículos;

  • classe Modelo - representa os modelos dos veículos;

  • classe Acessorio - representa os acessórios dos veículos;

  • AlfaDbContext - representa uma sessão com o banco de dados;

Vamos usar o recurso Data Annotations alguns requisitos das propriedades e validação das entidades.

A seguir inclua o código abaixo em cada um destes arquivos:

1- Classe Marca

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
namespace Alfa.Models
{
    public class Marca
    {
        public int Id {get; set; }
        [Required]
        [StringLength(255)]
        public string Nome {get;set;}
        public ICollection<Modelo> Modelos {get;set;}
        public Marca()
        {
            Modelos = new Collection<Modelo>();
        }
    }
}

Temos aqui a definição de um relacionamento um para muitos, onde uma Marca pode ter muitos Modelos. Isso é representando pela definição da coleção Modelos.

O construtor da classe inicializa a coleção Modelos pois isso é uma responsabilidade da classe Marca.

2- Classe Modelo

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Alfa.Models
{
    [Table("Modelos")]
    public class Modelo
    {
        public int Id { get; set; }

        [Required]
        [StringLength(255)]
        public string Nome { get; set; }
        public Marca Marca { get; set; }
        public int MarcaId { get; set; }
    }
}

O Data Annotations define que o nome da tabela gerada no mapeamento será Modelos, e que o cmapo Nome é obrigatório e tem o tamanho de 255 caracteres.

3- Classe Acessorio

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace Alfa.Models
{
     [Table("Acessorios")]
    public class Acessorio
    {
         public int Id { get; set; }
         [Required]
         [StringLength(255)]

         public string Nome { get; set; }
    }
}

O Data Annotations define que o nome da tabela gerada no mapeamento será Acessorios, e que o campo Nome é obrigatório e tem o tamanho de 255 caracteres.

4- Classe AlfaDbContext

using Alfa.Models;
using Microsoft.EntityFrameworkCore;
namespace Alfa.Models
{
    public class AlfaDbContext : DbContext
    {
        public AlfaDbContext(DbContextOptions<AlfaDbContext> options)
         : base (options)
        {}
        public DbSet<Marca> Marcas { get; set; }
        public DbSet<Acessorio> Acessorios { get; set; }
    }
}

Esta classe deriva de DbContext e expõe as propriedades DbSet que representam as coleções das entidades especificadas no contexto.

Essa classe é chamada de classe de contexto do banco de dados e coordena a funcionalidade do Entity Framework para um dado modelo de dados. No código dessa classe você especifica quais entidades estão incluídas no modelo de dados.

Observe que não foi necessário definir um DbSet para Modelo visto que ela esta relacionada com a entidade Marca.

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. Mais adiante iremos definir no construtor do controlador a instância do contexto.

Para registrar o nosso contexto AlfaDbContext como um serviço, abra o arquivo Startup.cs e adicione as linhas realçadas ao método ConfigureServices:

using Microsoft.EntityFrameworkCore;
using Alfa.Models;

...
....

    
  // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
          
 services.AddDbContext<AlfaDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ConexaoAlfa")));

            // Add framework services.
            services.AddMvc();
        }
....

O nome da string de conexão é passada para o contexto pela chamada do método no objeto DbContextOptionsBuilder. Para o desenvolvimento local a ASP .NET Core obtém a string de conexão do arquivo appsettings.json.

Vamos abrir o arquivo appsettings.json e adicionar a string de conexão conforme mostrado a seguir:

{ "ConnectionStrings" : {
 "ConexaoAlfa" : "Server=(localdb)\\mssqllocaldb;Database=Alfa;Trusted_Connection=True;MultipleActiveResultSets=true;"
},

  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

A string de conexão especifica um banco de dados identificado pelo nome Alfa.

Gerando o banco de dados e as tabelas usando Migrations

Agora  podemos usar o Migration do EF Core para criar o nosso banco de dados.

Abra uma janela do Package Manager Console via menu Tools e digite o comando : add-Migration ModeloInicial

Após a conclusão do comando verifique os arquivos criados na pasta Migrations do projeto e veja se o mapeamento esta correto.

A seguir na janela do Package Manager Console digite o comando : update-database

Ao final desta etapa teremos o banco de dados Alfa.mdf e as tabelas Marcas, Modelos e Acessorios criadas no banco de dados.

Precisamos agora incluir algumas informações nestas tabelas para podermos usá-las no projeto.

Para isso vamos criar uma migração vazia e depois vamos definir os dados que vamos incluir.

Digite o comando na janela Package Manager Console : add-migration SeedDatabase

Agora abra o arquivo SeedDatabase e você verá que temos a classe SeedDatabase contendo os métodos Up e Down vazios.

Inclua o código abaixo nestes métodos para poder preencher as tabelas com dados:

using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Alfa.Migrations
{
    public partial class SeedDatabase : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            //Marcas
            migrationBuilder.Sql("INSERT INTO Marcas (Nome) VALUES ('Ford')");
            migrationBuilder.Sql("INSERT INTO Marcas (Nome) VALUES ('GM')");
            migrationBuilder.Sql("INSERT INTO Marcas (Nome) VALUES ('Honda')");
            //Modelos
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Fiesta', (SELECT Id FROM Marcas Where Nome= 'Ford'))");
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Ka', (SELECT Id FROM Marcas Where Nome= 'Ford'))");
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Eco Esport', (SELECT Id FROM Marcas Where Nome= 'Ford'))");
            //Modelos
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Prisma', (SELECT Id FROM Marcas Where Nome= 'GM'))");
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Onix', (SELECT Id FROM Marcas Where Nome= 'GM'))");
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Cruze', (SELECT Id FROM Marcas Where Nome= 'GM'))");
            //modelos
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Civic', (SELECT Id FROM Marcas Where Nome= 'Honda'))");
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('Fit', (SELECT Id FROM Marcas Where Nome= 'Honda'))");
            migrationBuilder.Sql("INSERT INTO Modelos (Nome, MarcaId) VALUES ('HRV Suv', (SELECT Id FROM Marcas Where Nome= 'Honda'))");
            //acessórios
            migrationBuilder.Sql("INSERT INTO Acessorios (Nome) VALUES ('Ar Condicionado')");
            migrationBuilder.Sql("INSERT INTO Acessorios (Nome) VALUES ('Bancos de Couro')");
            migrationBuilder.Sql("INSERT INTO Acessorios (Nome) VALUES ('Câmera de Ré')");

        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql("DELETE FROM Marcas WHERE Nome IN ('Ford','GM','Honda')");
            migrationBuilder.Sql("DELETE FROM Acessorios WHERE Nome IN ('Ar Condicionado', 'Bancos de Couro', 'Câmera de Ré')");
        }
    }
}

O método Up permite fazer o upgrade para uma nova migração alterando as tabelas e incluindo dados e o método Down permite fazer o downgrade para a versão anterior.

A seguir na janela do Package Manager Console digite o comando : update-database

Se você verificar no SQL Server Management Studio ou no SQL Server Object Explorer vai encontrar as tabelas criadas e com os dados informados.

Assim já temos tudo pronto para poder iniciar a criação da nossa Web API.

Na próxima parte do artigo vamos criar a nossa ASP .NET Core Web API.

Sabendo, amados irmãos, que a vossa eleição é de Deus;Porque o nosso evangelho não foi a vós somente em palavras, mas também em poder, e no Espírito Santo, e em muita certeza, como bem sabeis quais fomos entre vós, por amor de vós.
1 Tessalonicenses 1:4,5

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