Facebook Pixel
Acessando Dados com .NET Core – Preparando o Ambiente

Acessando Dados com .NET Core – Preparando o Ambiente

Este artigo é parte da série:

Para esta etapa do projeto, vamos criar um novo controller, chamado “DadosController” na pasta “Controllers”. Atente-se ao detalhe que é uma “API Controlller” e não “MVC Controller” conforme vem no padrão.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Treino_REST_02.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ADOMetodoController : ControllerBase
    {
    }
}

E vamos começar colocando um nome na nova rota. Neste exercício, vamos chamar de “Dados”.

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Treino_REST_02.Controllers
{
    [Route("api/Dados")]
    [ApiController]
    public class DadosController : ControllerBase
    {
    }
}

A rotina que fizemos para o código “BasicoAPIController” possui todas a operações de CRUD (Create, Retrieve, Update, Delete) sendo executadas contra um listagem interna, em memória. O que vamos fazer agora e copiar todos os métodos daquela classe e remover os conteúdos dos métodos. E escrever novos conteúdos, desta vez realizando a operações de CRUD contra um banco de dados.

Esse controller “Dados” não vai fazer nada. Neste momento vai ser apenas um esqueleto para escrevermos os métodos de acesso a dados que virão nos próximos exercício. Por isso vamos deixar propositalmente os conteúdos dos métodos vazios.

Alguns cuidados que foram tomados ao copiar e colar o código:

  • Trocar o nome em [Route].
  • Trocar os nomes nos métodos, para evitar o conflito com a classe existente. Todos os métodos ganharam um “-Dados” ao final de seus nomes.
  • Inserir retorno em todos os métodos, nem que seja “BadRequest” para que este código vazio não apresente erro.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Treino_REST_02.Models;

namespace Treino_REST_02.Controllers
{
    /// <summary>
    /// Esqueleto para realizar operações CRUD.
    /// </summary>
    [Route("api/Dados")]
    [ApiController]
    public class DadosController : ControllerBase
    {

        IConfiguration Config;
        public List<UF> UFs = new List<UF>();

        /// <summary>
        /// Construtor inicia objeto Config
        /// </summary>
        /// <param name="_config"></param>
        public DadosController(IConfiguration _config) 
        {
            this.Config = _config;
        }

        /// <summary>
        /// Relação de todas as UFs com suas capitais
        /// </summary>
        /// <returns></returns>
        [HttpGet(Name = "ListaUF-Dados")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<IEnumerable<UF>> ListaUF()
        {
            return Ok(UFs);
        }

        /// <summary>
        /// Mostra os dados de uma UF específica
        /// </summary>
        /// <remarks>
        /// Caso o id não exista, retorna 404 Not Found. Caso id seja zero retorna Bad Request.
        /// </remarks>
        /// <param name="IdUF">Id da UF que será mostrada</param>
        /// <returns>Um JSON contendo os dados da UF selecionada.</returns>
        [HttpGet("{IdUF:int}", Name = "MostraUF-Dados")]
        [ProducesResponseType(200)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult<UF> MostraUF(int IdUF)
        {
            return BadRequest();
        }

        /// <summary>
        /// Adiciona uma nova UF à lista
        /// </summary>
        /// <param name="NovaUF"></param>
        /// <returns></returns>
        [HttpPost(Name = "Adiciona-Dados")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<IEnumerable<UF>> AdicionaUF(UF NovaUF)
        {
            return ListaUF();
        }

        /// <summary>
        /// Altera todos os dados de uma UF baseado em um id
        /// </summary>
        /// <param name="IdUF">Id da UF que será alterada</param>
        /// <param name="NomeUF">Novo nome (sigla) da UF</param>
        /// <param name="CapitalUF">Novo nome da capital</param>
        /// <returns></returns>
        [HttpPut(Name = "Altera-Dados")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<IEnumerable<UF>> AtualizaUF(int IdUF, string NomeUF, string CapitalUF)
        {
            return ListaUF();
        }

        /// <summary>
        /// Muda apenas a capital de uma UF baseado no nome da UF
        /// </summary>
        /// <param name="NomeUF">Nome da UF (sigla)</param>
        /// <param name="NovaCapital">Nome da nova capital</param>
        /// <returns></returns>
        [HttpPatch(Name = "MudaCapital-Dados")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<IEnumerable<UF>> MudaCapital(string NomeUF, string NovaCapital)
        {
            return ListaUF();
        }

        /// <summary>
        /// Elimina uma UF baseado no id
        /// </summary>
        /// <param name="DelId">Id da UF que será eliminada</param>
        /// <returns></returns>
        [HttpDelete(Name = "EliminaUF-Dados")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult<IEnumerable<UF>> EliminaUF(int DelId)
        {
            return ListaUF();
        }
    }
}

Vamos também incrementar a classe “UF.cs” para incluir as “Annotations”. Elas serão importantes depois para as operações envolvendo bancos de dados.

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

namespace Treino_REST_02.Models
{
    [Table("Capitais")]
    public class UF
    {
        [Required] 
        [Column("Id",TypeName = "int")]
        [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required] 
        [Column("UF", TypeName = "char")] 
        [MaxLength(2)]
        public required string Nome { get; set; }

        [Required] 
        [Column("Capital",TypeName = "varchar")] 
        [MaxLength(50)]
        public string? Capital { get; set; }

    }
}

Tendo feito essas operações, agora temos um esqueleto de operações CRUD que, até o momento ainda não faz nada, mas já responde no Swagger.

Ainda nessa parte de preparação do ambiente, vamos já definir a Connection String, pois o padrão MVC tem um lugar especial para ela no arquivo “appsettings.json”, conforme pode ser visto nas linhas 9, 10 e 11:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "cnMain": "Server=localhost;Database=Treino01;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Para fazer a leitura da ConnectionString dentro do código do programa, vamos instanciar um objeto da classe IConfiguration da seguinte forma:

namespace Treino_REST_02.Controllers
{
    [Route("api/Dados")]
    [ApiController]
    public class DadosController : ControllerBase
    {

        IConfiguration Config;

        public DadosController(IConfiguration _config) 
        {
            this.Config = _config;
        }

Apesar de a referência para IConfiguration ser passada no construtor, observe que instanciei o objeto “Config” no nível da classe e não dentro do método construtor. Dessa forma, “Config” pode ser chamado por qualquer método do programa. Para ler a string de conexão agora basta utilizar o método “Config.GetConnectionString()” como no exemplo abaixo:

Cn.ConnectionString = Config.GetConnectionString("cnMain");

Outra forma de fazer a leitura da string de conexão sem precisar deixar um objeto instanciado é essa abaixo, porém tenho a impressão que este método demanda mais recursos computacionais. Ainda farei uma pesquisa sobre o assunto para chegar à uma conclusão final.

var cnStr = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("ConnectionStrings")["cnMain"];

O próximo passo vai ser implementar o acesso a dados tanto com ADO.NET quanto com Entity Framework.

Deixe seu comentário