Neste artigo vou mostrar como consumir o serviço REST criado sobre a plataforma .NET, no artigo anterior, usando o framework ASP .NET Web API em um projeto WPF Application. |
No artigo anterior criamos nossa Web API usando o framework ASP .NET Web API com o nome WebApi2_Estudantes e já temos o serviço REST que expõe os serviços para realizar o acesso e as operações CRUD com as informações dos estudantes.
É neste momento que os serviços
REST fazem a diferença em relação ao protocolo
SOAP. Consumir um serviço SOAP é mais
complexo e precisa de todo um suporte de ferramentas visto que temos que
formatar as mensagens de envio e interpretar as mensagens de erro
No caso da plataforma .NET a Microsoft facilitou bastante a nossa vida
fornecendo recursos que facilitam o consumo de serviços REST (leia-se Web API).
Para consumirmos serviços REST em aplicações .NET, primeiro temos que usar os
recursos do assembly System.Net.Http.dll. Neste assembly temos o
namespace System.Net.Http, que possui tipos para consumir serviços
baseados exclusivamente no protocolo HTTP.
Para fazer isso basta referenciar o pacote “Microsoft.AspNet.WebApi.Client“
(via nuget) no projeto cliente que vai consumir a Web API.
Do lado do cliente a classe principal é a HttpClient que é responsável
por gerenciar toda a comunicação com um determinado serviço.
A classe HttpClient expõe os métodos para consumo dos serviços de forma
assíncrona , e métodos nomeados aos principais verbos HTTP que trabalham com as
classes HttpRequestMessage e HttpResponseMessage. (isso dá ao
cliente o controle sobre a mensagem enviada e da resposta que é retornada)
Vou então mostrar consumir essa Web API em um projeto WPF Application.
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 WPF no VS 2015 Community
Abra o VS Community 2015 e clique em New Project;
Selecione a linguagem Visual C# ->WPF Application
Informe o nome Consumindo_WebAPI_Estudantes e clique no botão OK;
Será criado um projeto WPF com a seguinte estrutura exibida no Solution Explorer:
Referenciando o pacote Microsoft.AspNet.WebApi.Client no projeto via Nuget
Para poder acessar a Web API vamos precisar referenciar o pacote “Microsoft.AspNet.WebApi.Client" em nosso projeto WPF.
No menu Tools clique em Nuget Package Manager -> Manage Nuget Packages for Solution;
Localize o pacote e instale no projeto:
Definindo a classe Estudante
Precisamos definir uma classe Estudante com as mesmas propriedades da classe Estudante definida no projeto Web API:
public
class
Estudante { public string nome { get; set; } public int id { get; set; } public string genero { get; set; } public int idade { get; set; } } |
Definindo a interface com o usuário
Vamos abrir o arquivo MainWindow.xaml e no editor XAML incluir os seguintes controles a partir da ToolBox:
Window - Title="Manutenção de Estudantes" Height="500" Width="525" Background="Chocolate"
TextBlock - Lista de Estudantes
ListView - estudanteListView
TextBlock - Adiciona ou Atualiza um estudante
TextBox - txtNomeEstudante
TextBox - txtIDEstudante
Combobox - cbxGenero
TextBox - txtIdade
2 Button - btnNovoEstudante(btnNovoEstudante_Click) e btnAtualiza(btnAtualiza_Click)
TextBlock - Obtém ou deleta um estudante
TextBlock - Informe o id do estudate
TextBox - txtID
2 Buttons - btnGetEstudante (btnGetEstudante_Click) e btnDeletaEstudante (btnDeletaEstudante_Click)
A seguir disponha os controles conforme o leiaute abaixo:
O código completo do arquivo MainWindow.xaml é dado a seguir:
<Window x:Class="Consumindo_WebAPI_Estudantes.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Consumindo_WebAPI_Estudantes" mc:Ignorable="d" Title="Manutenção de Estudantes" Height="500" Width="525" Background="Chocolate"> <Window.Resources> <ControlTemplate x:Key="btnTemplate" TargetType="Button"> <Grid> <Rectangle RadiusX="5" RadiusY="5" Fill="Aquamarine"> </Rectangle> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter> </Grid> </ControlTemplate> <Style TargetType="TextBlock"> <Setter Property="Foreground" Value="White"/> <Setter Property="FontSize" Value="13"></Setter> </Style> <Style x:Key="tbkStyle" TargetType="TextBlock"> <Setter Property="Foreground" Value="White"/> <Setter Property="FontSize" Value="13"></Setter> </Style> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="2*"></ColumnDefinition> </Grid.ColumnDefinitions> <StackPanel x:Name="estudantePanel" Grid.Column="0"> <TextBlock Text="Lista de Estudantes" FontSize="18" FontWeight="Bold"></TextBlock> <ListView x:Name="estudantesListView" Margin="0,10,0,0" Background="Transparent" Height="400" ScrollViewer.CanContentScroll="True"> <ListView.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Style="{StaticResource tbkStyle}"> <TextBlock.Inlines> <Run Text="Nome : "></Run> <Run Text="{Binding nome}"></Run> </TextBlock.Inlines> </TextBlock> <TextBlock Style="{StaticResource tbkStyle}"> <TextBlock.Inlines> <Run Text="ID : "></Run> <Run Text="{Binding id}"></Run> </TextBlock.Inlines> </TextBlock> <TextBlock Style="{StaticResource tbkStyle}"> <TextBlock.Inlines> <Run Text="Gênero : "></Run> <Run Text="{Binding genero}"></Run> </TextBlock.Inlines> </TextBlock> <TextBlock Style="{StaticResource tbkStyle}"> <TextBlock.Inlines> <Run Text="Idade : "></Run> <Run Text="{Binding idade}"></Run> <LineBreak/> </TextBlock.Inlines> </TextBlock> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackPanel> <Grid Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Margin="10,0,0,0"> <TextBlock Text="Adiciona ou Atualiza um estudante" FontSize="18" FontWeight="Bold"></TextBlock> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="Nome" Width="75"></TextBlock> <TextBox x:Name="txtNomeEstudante" Margin="10,0,0,0" Width="200"></TextBox> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="ID" Width="75"></TextBlock> <TextBox x:Name="txtIDEstudante" Margin="10,0,0,0" Width="200"></TextBox> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="Genero" Width="75"></TextBlock> <ComboBox x:Name="cbxGenero" Margin="10,0,0,0" Width="200" Text="--Selecione o sexo--" IsReadOnly="True" IsEditable="True"></ComboBox> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="Idade" Width="75"></TextBlock> <TextBox x:Name="txtIdade" InputScope="Number" Margin="10,0,0,0" Width="200"></TextBox> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <Button x:Name="btnNovoEstudante" Template="{StaticResource btnTemplate}" Content=" Adiciona um estudante " Margin="0,0,10,0" Click="btnNovoEstudante_Click"></Button> <Button x:Name="btnAtualiza" Template="{StaticResource btnTemplate}" Content=" Atualiza um estudante " Click="btnAtualiza_Click"></Button> </StackPanel> </StackPanel> <StackPanel Grid.Row="1" Margin="10,0,0,0"> <TextBlock Text="Obtém ou Deleta um estudante" FontSize="18" FontWeight="Bold"></TextBlock> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="Informe o Id do Estudante" Width="150"></TextBlock> <TextBox x:Name="txtID" InputScope="Number" Margin="10,0,0,0" Width="100"></TextBox> </StackPanel> <StackPanel x:Name="estudanteDetalhesPanel" Margin="10,0,0,0" Visibility="Collapsed"> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="Nome :" Width="75"></TextBlock> <TextBlock x:Name="txbEstudanteNome" Text="{Binding nome}" Margin="10,0,0,0" Width="200"></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="ID : " Width="75"></TextBlock> <TextBlock x:Name="txbEstudanteID" Margin="10,0,0,0" Text="{Binding id}" Width="200"></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="Gênero : " Width="75"></TextBlock> <TextBlock x:Name="txbGenero" Margin="10,0,0,0" Text="{Binding genero}" Width="200"></TextBlock> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <TextBlock Text="Idade : " Width="75"></TextBlock> <TextBlock x:Name="txbIdade" InputScope="Number" Margin="10,0,0,0" Width="200" Text="{Binding Idade}"> </TextBlock> </StackPanel> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,10,0,0"> <Button x:Name="btnGetEstudante" Template="{StaticResource btnTemplate}" Content=" Obtém um estudante " Margin="0,0,10,0" Click="btnGetEstudante_Click"></Button> <Button x:Name="btnDeletaEstudante" Template="{StaticResource btnTemplate}" Content=" Deleta um estudante " Click="btnDeletaEstudante_Click"></Button> </StackPanel> </StackPanel> </Grid> </Grid> </Window> |
Este código desenha a nossa interface na aplicação WPF. Vamos agora implementar o código no arquivo code-behind MainWindow.xaml.cs.
Definindo o código do projeto WPF
Abra o arquivo MainWindow.xaml.cs e defina o código que irá acessar a nossa Web API - WebApi2_Estudantes criada no artigo anterior.
Vamos começar definindo os namespaces usados. Inclua no início do arquivo as seguintes declaração de namespaces:
using
System;A seguir vamos criar uma instância da classe HttpClient que iremos usar no projeto.
HttpClient
client = new HttpClient();Do lado
do cliente a classe principal é a HttpClient que é responsável por
gerenciar toda a comunicação com um determinado serviço.
A classe HttpClient expõe os métodos para consumo dos serviços de forma
assíncrona , e métodos nomeados aos principais verbos HTTP que trabalham com as
classes HttpRequestMessage e HttpResponseMessage. (isso dá ao
cliente o controle sobre a mensagem enviada e da resposta que é retornada)
Definindo o código no método MainWindow()
O método MainWindow() será executado quando a aplicação WPF for iniciada. Logo após a chamada do método InitializeComponent() vamos definir o código que realiza as seguintes tarefas:
public MainWindow() { InitializeComponent(); List<string> generoLista = new List<string>(); generoLista.Add("Masculino"); generoLista.Add("Feminino"); cbxGenero.ItemsSource = generoLista; client.BaseAddress = new Uri("http://localhost:51133"); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); this.Loaded += MainWindow_Loaded; } |
A seguir o código do evento Loaded :
async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
try
{
HttpResponseMessage response = await client.GetAsync("/api/estudantes");
response.EnsureSuccessStatusCode(); // Lança um código de erro
var estudantes = await response.Content.ReadAsAsync<IEnumerable<Estudante>>();
estudantesListView.ItemsSource = estudantes;
}
catch(Exception)
{
//MessageBox.Show("Erro : " + ex.Message);
}
}
|
O evento assíncrono envia uma requisição GET de forma assíncrona usando a URI - /api/estudantes - e receber a resposta exibindo no ListView - estudantesListView através da propriedade ItemSource.
Vemos o resultado exibido na figura abaixo:
Assim ao iniciar teremos a lista de estudantes exibida no ListView.
Vamos definir um método chamado GetAllEstudantes() que será usado no projeto para atualizar a exibição do controle ListView exibindo as informações após realizarmos uma operação :
O código deste método é dado a seguir :
public async Task<IEnumerable<Estudante>> GetAllEstudantes()
{
HttpResponseMessage response = await client.GetAsync("/api/estudantes");
response.EnsureSuccessStatusCode(); //lança um código de erro
var estudantes = await response.Content.ReadAsAsync<IEnumerable<Estudante>>();
return estudantes;
}
|
Este código envia uma requisição GET para a URI indicada e retorna uma lista de objeto Estudante.
Agora vamos definir os métodos que irão acessar a Web API e realizar as operações desejadas:
1- Obter um estudante pelo seu id
private async void btnGetEstudante_Click(object sender, RoutedEventArgs e)
{
try
{
HttpResponseMessage response = await client.GetAsync("/api/estudantes/" + txtID.Text);
response.EnsureSuccessStatusCode(); //lança um código de erro
var estudantes = await response.Content.ReadAsAsync<Estudante>();
estudanteDetalhesPanel.Visibility = Visibility.Visible;
estudanteDetalhesPanel.DataContext = estudantes;
}
catch (Exception)
{
MessageBox.Show("Estudante não localizado");
}
}
|
|
|
Neste código enviamos uma requisição GET usando a URI - /api/estudantes/" + txtID.Text - onde txtID.Text é o código do estudante.
A resposta é exibida no Panel - estudanteDetalhesPanel - usando a propriedade DataContext:
2- Adicionar um estudante
private async void btnNovoEstudante_Click(object sender, RoutedEventArgs e)
{
try
{
var estudante = new Estudante()
{
nome = txtNomeEstudante.Text,
id = int.Parse(txtIDEstudante.Text),
genero = cbxGenero.SelectedItem.ToString(),
idade = int.Parse(txtIdade.Text)
};
var response = await client.PostAsJsonAsync("/api/estudantes/", estudante);
response.EnsureSuccessStatusCode(); //lança um código de erro
MessageBox.Show("Estudante incluído com sucesso", "Result", MessageBoxButton.OK,
MessageBoxImage.Information);
estudantesListView.ItemsSource = await GetAllEstudantes();
estudantesListView.ScrollIntoView(
estudantesListView.ItemContainerGenerator.Items[estudantesListView.Items.Count - 1]);
}
catch (Exception)
{
MessageBox.Show("O Estudante não foi incluído. (Verifique se o ID não esta duplicado)");
}
}
|
|
|
Neste código cria uma instância da classe Estudante e atribui a ela os dados informados no formulário. A seguir, usando o método PostAsJsonAsync, envia uma requisição POST como uma operação assíncrona para a URI - /api/estudate - passando o objeto estudante serializado.
Para exibir o resultado e atualizar a exibição do controle ListView chamamos o método GetAllEstudantes().
3- Atualiza um estudante
private async void btnAtualiza_Click(object sender, RoutedEventArgs e)
{
try
{
var estudante = new Estudante()
{
nome = txtNomeEstudante.Text,
id = int.Parse(txtIDEstudante.Text),
genero = cbxGenero.SelectedItem.ToString(),
idade = int.Parse(txtIdade.Text)
};
var response = await client.PutAsJsonAsync("/api/estudantes/", estudante);
response.EnsureSuccessStatusCode(); //lança um código de erro
MessageBox.Show("Estudante atualizado com sucesso", "Result", MessageBoxButton.OK,
MessageBoxImage.Information);
estudantesListView.ItemsSource = await GetAllEstudantes();
estudantesListView.ScrollIntoView(
estudantesListView.ItemContainerGenerator.Items[estudantesListView.Items.Count - 1]);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
|
|
|
Neste código cria uma instância da classe Estudante e atribui a ela os dados informados no formulário. A seguir, usando o método PutAsJsonAsync, envia uma requisição PUT como uma operação assíncrona para a URI - /api/estudate - passando o objeto estudante serializado.
Para exibir o resultado e atualizar a exibição do controle ListView chamamos o método GetAllEstudantes().
4- Deleta um estudante
private async void btnDeletEstudante_Click(object sender, RoutedEventArgs e)
{
try
{
HttpResponseMessage response = await client.DeleteAsync("/api/estudantes/" + txtID.Text);
response.EnsureSuccessStatusCode(); //lança um código de erro
MessageBox.Show("Estudante deletado com sucesso");
estudantesListView.ItemsSource = await GetAllEstudantes();
estudantesListView.ScrollIntoView(
estudantesListView.ItemContainerGenerator.Items[estudantesListView.Items.Count - 1]);
}
catch (Exception)
{
MessageBox.Show("Estudante deletado com sucesso");
}
}
|
|
|
Neste código usamos o método DeleteAsync, envia uma requisição DELETE como uma operação assíncrona para a URI -/api/estudantes/" + txtID.Text - onde txtID.Text é o id do estudante.
Para exibir o resultado e atualizar a exibição do controle ListView chamamos o método GetAllEstudantes().
Temos assim a nossa Web API definida no projeto WebApi2_Estudante sendo consumida em um projeto WPF Application.
Pegue o projeto WPF completo aqui : Consumindo_WebAPI_Estudantes.zip (sem as referências)
Porque toda a carne
é como a erva, e toda a glória do homem como a flor da erva. Secou-se a erva, e
caiu a sua flor;
Mas a palavra do Senhor permanece para sempre.E esta é a palavra que entre vós
foi evangelizada.
1 Pedro 1:24-25
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 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: