Xamarin Forms - Consumindo uma Web API ASP .NET com HttpClient - II


 Neste artigo vou mostrar como criar e consumir uma Web API ASP .NET em uma aplicação Xamarin Forms usando o HttpCliente com o Visual Studio 2015 e a linguagem C#.

Na primeira parte do artigo criamos nossa web api e fizemos o deploy do projeto no servidor Somee.com onde temos a API atendendo no endereço macwebapi.somee.com/api/produtos.

Vamos agora consumir essa web api em uma aplicação Xamarin Forms usando os recursos da classe HttpClient e da biblioteca Newtonsoft.Json.

Neste artigo irei criar o projeto Xamarin Forms e realizar as seguintes tarefas:

Ao trabalho...

Recursos usados:

Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.

Criando o projeto no Visual Studio 2015 Community

Abra o Visual Studio Community 2015 e clique em New Project;

Selecione Visual C#, o template Cross Plataform e a seguir Cross Plataform App(Xamarin.Forms or Native);

Informe o nome XF_ConsumindoWebAPI e clique no botão OK;

Observe que a nova versão do Xamarin Forms disponbilizada em Fevereiro/2017 trás novas opções de templates de projeto.

A seguir selecione Blank App e marque as opções - Xamarin.Forms e Portable Class Library (PCL) e clique em OK;

Será apresentada a janela abaixo, outra diferença da nova versão, onde você pode escolhar os templates Blank App e Master Detail e a seguir a tecnologia e o tipo de projeto.

Marque as opções Blank App, Xamarin.Forms e Portable Class Library(PCL)  e clique em OK.

Será criado uma solução contendo no projeto Portable as páginas App.xaml e MainPage.xaml. Essa é outra diferença que a nova versão trouxe.

No code-behind do arquivo App.xaml temos a classe App.cs que irá conter o código compartilhado e que vamos usar neste artigo.

Iremos usar a página MainPage.xaml como página principal da nossa aplicação.

Assim se você abrir o arquivo App.cs verá alterar o código já definido conforme o mostrado abaixo que abre a página MainPage :

using Xamarin.Forms;

namespace XF_Bindable_Spinner
{
    public class App : Application
    {
        public App()
        {        

  MainPage = new NavigationPage(new XF_PaginaPesquisa.MainPage());   
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}

Incluindo as referências ao HttpClient e NewtonSoft no projeto

Precisamos incluir duas referências em nosso projeto. Os pacotes :

No menu Tools clique em Nuget Package Manager e a seguir em Manage Nuget Packages for Solution;

Selecione a guia Browse e informe httpclient;

A seguir selecione o pacote Microsoft.Net.HttpClient e marque a para instalar em todos os projetos e clique em Install;

Repita o procedimento para o pacote Newtonsoft.Json:

Definindo o modelo de domínio : a classe Produto

Vamos criar a classe Produto que será o nosso modelo de domínio e que vamos usar para obter as informações da web api.

Crie uma pasta chamada Models no projeto portable e a seguir crie a classe Produto.cs com o seguinte código:

 public class Produto
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public string Categoria { get; set; }
        public decimal Preco { get; set; }
    }

Essa classe possui exatamente as mesmas propriedades da classe Produto definida na web api.

Definindo a camada de serviço:  a classe DataService

Vamos criar uma nova pasta chamada Service no projeto Portable e nesta pasta criar a classe DataService.

Essa classe contém o código que usa os recursos do HttpClient e do Newtonsoft.Json para enviar requisições HTTP e receber respostas HTTP a partir da url da nossa web api e tratar os dados no formato JSON.

Abaixo temos o código da classe DataService:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using XF_ConsumindoWebAPI.Models;

namespace XF_ConsumindoWebAPI.Service
{
    public class DataService
    {
        HttpClient client = new HttpClient();

        public async Task<List<Produto>> GetProdutosAsync()
        {
            try
            {
                string url = "http://www.macwebapi.somee.com/api/produtos/";
                var response = await client.GetStringAsync(url);
                var produtos = JsonConvert.DeserializeObject<List<Produto>>(response);
                return produtos;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public async Task AddProdutoAsync(Produto produto)
        {
            try
            {
                string url = "http://www.macwebapi.somee.com/api/produtos/{0}";

                var uri = new Uri(string.Format(url, produto.Id));

                var data = JsonConvert.SerializeObject(produto);
                var content = new StringContent(data, Encoding.UTF8, "application/json");

                HttpResponseMessage response = null;

                response = await client.PostAsync(uri, content);

                if (!response.IsSuccessStatusCode)
                {
                    throw new Exception("Erro ao incluir produto");
                }
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

        public async Task UpdateProdutoAsync(Produto produto)
        {
            string url = "http://www.macwebapi.somee.com/api/produtos/{0}";
            var uri = new Uri(string.Format(url, produto.Id));

            var data = JsonConvert.SerializeObject(produto);
            var content = new StringContent(data, Encoding.UTF8, "application/json");

            HttpResponseMessage response = null;
            response = await client.PutAsync(uri, content);

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception("Erro ao atualizar produto");
            }

        }

        public async Task DeletaProdutoAsync(Produto produto)
        {
            string url = "http://www.macwebapi.somee.com/api/produtos/{0}";
            var uri = new Uri(string.Format(url, produto.Id));
            await client.DeleteAsync(uri);
        }
    }
}

Nesta classe definimos métodos assíncronos para gerenciar os produtos remotamente acessando a nossa web api definida no endereço : http://www.macwebapi.somee.com/api/produtos

Assim temos os métodos :

O código esta classe foi baseado na documentação do Xamarin neste link: https://developer.xamarin.com/guides/xamarin-forms/cloud-services/consuming/rest/

Criando a página para gerenciar produtos

Vamos criar a página da nossa aplicação Xamarin Forms no arquivo MainPage.xaml usando uma view ListView onde iremos usar os seguintes recursos:

Vamos incluir no topo da ListView 3 views Entry para exibir os dados do produto selecionado que poderá assim ser alterado, e ,uma view Button onde poderemos incluir ou alterar um produto.

Abra o arquivo MainPage.xaml e altere o seu código conforme mostrado a seguir: (Ao lado você vê o layout da página que será exibida ao cliente)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XF_ConsumindoWebAPI"
             x:Class="XF_ConsumindoWebAPI.MainPage">

    <StackLayout Orientation="Vertical">
        <StackLayout Padding="5,5,0,0">
            <Label Text="Adicionar um Produto" TextColor="Green" />
        </StackLayout>
        <StackLayout Padding="10,0,10,0">
            <Entry x:Name="txtNome" Placeholder="Nome do produto" HorizontalOptions="Start"
                    VerticalOptions="StartAndExpand" HeightRequest="30" WidthRequest="300" FontSize="Small"/>
            <Entry x:Name="txtCategoria" Placeholder="Categoria do produto" HorizontalOptions="Start"
                    VerticalOptions="StartAndExpand" HeightRequest="30" WidthRequest="300" FontSize="Small" />
            <Entry x:Name="txtPreco" Placeholder="Preço do produto" HorizontalOptions="Start" VerticalOptions="StartAndExpand"
                    HeightRequest="30" WidthRequest="300" FontSize="Small" />
            <Button HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand" HeightRequest="40" Text="Adicionar/Atualizar Produto"
                    Clicked="btnAdicionar_Clicked" FontSize="Small"/>
        </StackLayout>

        <StackLayout Orientation="Vertical" Padding="10,5,10,0">
            <ListView x:Name="listaProdutos" ItemSelected="listaProdutos_ItemSelected" BackgroundColor="Aqua" SeparatorColor="Blue">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.ContextActions>
                                <MenuItem Clicked="OnAtualizar" CommandParameter="{Binding .}" Text="Atualizar" />
                                <MenuItem Clicked="OnDeletar" CommandParameter="{Binding .}" Text="Deletar" IsDestructive="True" />
                            </ViewCell.ContextActions>
                            <StackLayout Padding="10,10" Orientation="Horizontal">
                                <Label Text="{Binding Nome}" HorizontalOptions="StartAndExpand"/>
                                <Label Text="{Binding Categoria}" TextColor="Blue" HorizontalOptions="Center"/>
                                <Label Text="{Binding Preco}" HorizontalOptions="End"/>

                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </StackLayout>

</ContentPage>

 

Na continuação do artigo vamos definir o código do arquivo MainPage.xaml.cs para incluir, alterar, excluir e acessar serviço exposto pela web api e gerenciar as informações dos produtos.

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

Referências:


José Carlos Macoratti