.NET Core - Consumindo uma API com Windows Forms


Hoje vamos recordar como consumir uma Web API em uma aplicação Windows Forms no ambiente do  .NET Core.

Já faz algum tempo que já podemos criar projetos Windows Forms no .NET 5.0 usando praticamente os mesmos recursos que no .NET Framework.  Só tem um detalhe : as aplicações só rodam no ambiente Windows.

Eu também já mostrei como consumir uma API usando uma aplicação Windows Forms; tudo isso no ambiente do .NET Framework. (Veja as referências)

Hoje vou mostrar como consumir uma WEB API ASP .NET Core em um projeto Windows Forms criado no .NET Core 5.0.

Vou partir do ponto onde já temos uma API ASP .NET Core em execução e expondo os seus endpoints.

Podemos acessar esta API e retornar informações de Produtos e para isso teremos que realizar a autenticação e obter um token JWT na aplicação Windows Forms para poder acessar os produtos e exibir os dados no formulário Windows Forms em um controle DataGridView.

Para acessar a API teremos que usar a URI de acesso no endereço: http://localhost:44390/api

Os endpoints para realizar a autenticação e para obter os produtos da Api são:

Criando o projeto Windows Forms no .NET 5.0

Assim vamos criar um projeto Windows Forms usando o VS Community 2019 usando o template Windows Forms App:

Vamos chamar o projeto de ConsomeAPI.

No projeto Windows Forms vamos criar a pasta Models e nesta pasta vamos criar a classe Produto que representa o produto para o qual vamos obter as informações da API:

public class Produto
 {
       public int ProdutoId { get; set; }
        public string Nome { get; set; }
        public string Descricao { get; set; }
        public decimal Preco { get; set; }
        public string ImagemUrl { get; set; }
        public int CategoriaId { get; set; }
}

A seguir vamos criar a classe AccessToken na pasta Models que representa os dados do token JWT que teremos que obter para acessar a API:

 public class AccessToken
 {
        public bool Authenticated { get; set; }
        public string Expiration { get; set; }
        public string Token { get; set; }
        public string Message { get; set; }
 }

Essas informações você geralmente obtém da API que deseja consumir.

Vamos agora incluir no projeto um arquivo de configuração App.Config para armazenar as informações referente ao endereço Base da api e as credenciais do usuário que vai se autenticar para obter o token JWT:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="UrlBase" value="https://localhost:44390/api/"/>
<add key="UserID" value="admin@yahoo.com" />
<add key="AccessKey" value="Numsey#2021"/>
</appSettings>

</configuration>

Criamos a seção appSettings e definimos os valores para as chaves : UrlBase, UserId e AccessKey que usaremos para realizar o acesso e autenticação na API.

Criando o serviço para acessar a API

Agora vamos criar uma pasta Services no projeto e nesta pasta vamos criar a classe AcessaAPIService onde vamos definir dois métodos :

  1. GetAllProdutos() - Para retornar todos os produtos
  2. GetHeaderTokenAuthorization() - Para armazenar o token JWT obtido na autenticação no header do request;
using ConsomeAPI.Models;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;

namespace ConsomeAPI.Services
{
    public class AcessaAPIService
    {
        public async Task<List<Produto>> GetAllProdutos(string URI, AccessToken accessToken)
        {
            using (var client = new HttpClient())
            {
                GetHeaderTokenAuthorization(client, accessToken);

                using (var response = await client.GetAsync((URI)))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var content = await response.Content.ReadAsStringAsync();
                        var options = new JsonSerializerOptions
                        {
                            IncludeFields = true,
                            PropertyNameCaseInsensitive = true
                        };
                        List<Produto> produtos = JsonSerializer.Deserialize<List<Produto>>(content, options);
                        return produtos;
                    }
                    else
                    {
                        throw new Exception("Não foi possível obter o produto: " + response.StatusCode);
                    }
                }
            }
        }

        public static void GetHeaderTokenAuthorization(HttpClient client, AccessToken accessToken)
        {
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

            client.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", accessToken.Token);
        }
    }
}

 

Com isso conseguimos acessar a API passando o token JWT associado ao Request das requisições. Observe que aqui estamos usando o System.Text.Json para realizar a desserialização dos dados no formato Json para uma lista de objetos Produtos usando o código:

var content = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
        IncludeFields = true,
         PropertyNameCaseInsensitive = true
 };
 List<Produto> produtos = JsonSerializer.Deserialize<List<Produto>>(content, options);
 return produtos;

Definindo o projeto Windows Forms

No formulário Windows Forms vamos criar uma interface para realizar a autenticação, obter os dados da API exibir os dados no formulário. Para isso vamos criar a seguinte interface:

Temos aqui os seguintes controles:

No início da classe Form1 vamos declarar as variáveis que serão visíveis em todo o Form:

 private string URI = "";
 private static string _urlBase;
 private static AccessToken accessToken;

No evento Click do botão Autenticar vamos incluir o código abaixo:

 private void btnAutenticar_Click(object sender, EventArgs e)
 {
            _urlBase = ConfigurationManager.AppSettings["UrlBase"];
            var email = ConfigurationManager.AppSettings["UserID"];
            var password = ConfigurationManager.AppSettings["AccessKey"];
            var confirmPassword = password;

            var urlbase = _urlBase + "autoriza/login";

            using (var client = new HttpClient())
            {
                string conteudo = "";

                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/json"));

                // Envio da requisição a fim de autenticar
                // e obter o token de acesso

                try
                {
                    HttpResponseMessage respToken =
                        client.PostAsync(urlbase, new StringContent(
                            JsonConvert.SerializeObject(new
                            {
                                email,
                                password,
                                confirmPassword
                            }), Encoding.UTF8, "application/json")).Result;

                    conteudo = respToken.Content.ReadAsStringAsync().Result;
                    btnProdutos.Enabled = true;

                    if (respToken.StatusCode == HttpStatusCode.OK)
                    {
                        accessToken = JsonConvert.DeserializeObject<AccessToken>(conteudo);

                        if (accessToken.Authenticated)
                        {

                            // Associar o token aos headers do objeto
                            // do tipo HttpClient

                            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",
accessToken.Token);

                            MessageBox.Show($"token JWT Autenticado ");
                        }
                        else
                        {
                            MessageBox.Show("Falha na autenticação");
                        }

                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erro " + ex.Message);
                }
            }
   }

Neste código estamos lendo as informações do arquivo App.Config e montando um request POST para realizar a autenticação do usuário.

Se ela for bem sucedida então vamos associar o token JWT recebido aos headers do objeto HttpClient para usar para acessar a API.

Agora no evento Click do botão  Retorna Produtos vamos incluir o seguinte código:

 private async void btnProdutos_Click(object sender, EventArgs e)
  {
            try
            {
                URI = txtURI.Text;
             
  var acessaAPI = new AcessaAPIService();
                List<Produto> produtos =
await acessaAPI.GetAllProdutos(URI, accessToken);
                dgvDados.DataSource = produtos;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro : " + ex.Message);
            }
 }

Neste código vamos usar o serviço que acessa a API e usando o método GetAllProdutos passamos a URI e o objeto accessToken para obter os dados dos produtos e exibir no controle DataGridView.

Executando o projeto iremos obter o resultado a seguir:

Código do Projeto:  ConsomeAPI.zip

"Paulo, apóstolo enviado, não da parte de homens nem por meio de pessoa alguma, mas por Jesus Cristo e por Deus Pai, que o ressuscitou dos mortos,"
Gálatas 1:1

Referências:


José Carlos Macoratti