Accediendo a un Servicio Web REST

Este artículo es una traducción del artículo original encontrado en: http://create.msdn.com/en-US/education/quickstarts/Accessing_a_REST_Web_Service.

 

 

Representational State Transfer (REST) ​​se refiere a un estilo arquitectónico para exponer recursos en la web para el acceso a los clientes.  Muchos recursos, como blogs, mapas y productos, se exponen como servicios REST en la web.  Silverlight proporciona clases que hacen que sea fácil llamar a los servicios REST desde una aplicación de Windows Phone.  Este tutorial presenta cómo llamar y trabajar con servicios REST.  Contiene las siguientes secciones:

  • Llamando servicios REST
  • Ejemplo para llamar un servicio REST
  • Detectando la disponibilidad de la red

Nota

Los ejemplos del uso de Silverlight se ejecutan en el navegador para simular su comportamiento para Windows Phone. El comportamiento real puede ser ligeramente diferente en el emulador de Windows Phone o en un dispositivo Windows Phone. 

Llamando servicios REST

Se llama a un servicio REST utilizando verbos estándar HTTP (GET, POST, PUT, y DELETE).  Los recursos son identificados por un URI.  Una respuesta contiene una representación, por lo general XML o JavaScript Object Notation (JSON), del recurso especificado.  Las peticiones no tienen estado, lo que significa que toda la información necesaria para completar una petición debe ser incluida con cada petición.

Un aspecto importante al llamar a un servicio REST es garantizar que se utiliza el URI correcto para el recurso que se está tratando de acceder.  Las empresas normalmente enlistan los requerimientos para una petición, incluyendo parámetros de la petición y los valores que debes pasar para dichos parámetros.  Por ejemplo, para llamar a los servicios Web de Bing, puede revisar la Guía del API de Bing.

Silverlight para Windows Phone proporciona varias clases para llamar servicios REST.  Es importante recordar, sin embargo, que en este momento Windows Phone soporta Silverlight 3, lo que significa que las características de red de Silverlight 4 no están disponibles para los clientes de Windows Phone.  Para obtener más información acerca de las diferencias en las capacidades de red entre Silverlight para Windows Phone y Silverlight para el escritorio, vea Redes en Silverlight para Windows Phone.

Para llamar a un servicio REST desde una aplicación cliente de Windows Phone, puedes utilizar las clases WebClient o HttpWebRequest y HttpWebResponse.  Con cualquiera de las opciones, las solicitudes son asincrónicas.  Sin embargo, WebClient es la más simple de las dos opciones.

WebClient utiliza un sistema simple basado en eventos para hacer peticiones y obtener respuestas.  Para utilizar WebClient, se llama al método apropiado Async y se maneja el evento Completed correspondiente.  La siguiente tabla enlista algunos de los métodos y eventos de WebClient que debes usar, dependiendo de la acción y del tipo de datos.

Acción

Tipo de datos

Métodos y eventos

GET

String

Método DownloadStringAsync
Evento DownloadStringCompleted

GET

Stream

Método OpenReadAsync
Evento OpenReadCompleted

POST

String

Método UploadStringAsync
Evento UploadStringCompleted

POST

Stream

Método OpenWriteAsync
Evento OpenWriteCompleted

La clase HttpWebRequest te permite tener más control sobre el mensaje de petición, como el envío de mensajes HTTP, PUT y DELETE. Para obtener más información sobre el uso de las clases HttpWebRequest y HttpWebResponse, consulta la información general de la clase HttpWebRequest.

Ejemplo para llamar un servicio REST

El siguiente ejemplo muestra cómo utilizar la clase WebClient para enviar una petición desde una aplicación de teléfono hacia el servicio de búsqueda de Bing.  En este ejemplo, puedes cambiar el término de búsqueda seleccionado utilizando el combo box, lo cual actualiza la URI de búsqueda.  Al hacer clic en el botón Search!, se envía una petición al servicio de búsqueda de Bing.  Además del término de búsqueda, el URI de la petición especifica que los resultados son una búsqueda Web y que la respuesta está en XML.  Los resultados son interpretados y mostrados en el list box.

Get Microsoft Silverlight

Nota

Aunque el ejemplo incluye un ID de Aplicación Bing en el URI para completar la petición de búsqueda, el ID de Aplicación real no se muestra en el código.  Para obtener un ID de Aplicación para llamar al servicio de búsqueda de Bing, consulta Introducción al API de Bing Versión 2.

Nota de seguridad

Cuando se conecta a un Servicio Web que requiere una clave de aplicación, no almacenes la clave de aplicación en una aplicación que se ejecutará en un dispositivo.  En su lugar, puedes crear un Servicio Web proxy para autenticar a un usuario y llamar a un servicio en la nube con la clave de aplicación.  Para obtener más información acerca de las recomendaciones de seguridad, consulta Seguridad en Servicios Web para Windows Phone.

El fragmento siguiente muestra el markup y el código para este ejemplo.

XAML

<phone:PhoneApplicationPage

x:Class="WindowsPhoneApplication1.MainPage"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"

xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"

FontFamily="{StaticResource PhoneFontFamilyNormal}"

FontSize="{StaticResource PhoneFontSizeNormal}"

Foreground="{StaticResource PhoneForegroundBrush}"

SupportedOrientations="Portrait" Orientation="Portrait"

shell:SystemTray.IsVisible="False">

<!–LayoutRoot es la red de la raíz donde se encuentra todo el contenido de la página –>

<Grid x:Name="LayoutRoot" Background="Transparent">

<Grid.Resources>

<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem" >

<Setter Property="Foreground" Value="Black"/>

<Setter Property="Background" Value="LightGray"/>

</Style>

<Style x:Key="ComboBoxStyle" TargetType="ComboBox" >

<Setter Property="Foreground" Value="Black"/>

<Setter Property="Background" Value="Gray"/>

</Style>

</Grid.Resources>

<Grid.RowDefinitions>

<RowDefinition Height="Auto"/>

<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<!–TitlePanel contiene el nombre de la aplicación y el título de la página –>

<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

<TextBlock x:Name="ApplicationTitle" Text="REST CLIENT"

Style="{StaticResource PhoneTextNormalStyle}"/>

<TextBlock x:Name="PageTitle" Text="bing search"

Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"

Height="99" Width="453" />

</StackPanel>

<!–ContentPanel – colocar el contenido adicional aquí –>

<Grid x:Name="ContentPanel" Margin="12,139,12,0" Grid.RowSpan="2">

<Button Content="Search!" Height="89" HorizontalAlignment="Left"

Margin="264,140,0,0" Name="button1"

VerticalAlignment="Top" Width="189" Click="button1_Click" />

<ComboBox Height="50" Style="{StaticResource ComboBoxStyle}"

HorizontalAlignment="Left" Margin="6,159" Name="comboBox1"

ItemContainerStyle="{StaticResource ComboBoxItemStyle}"

VerticalAlignment="Top" Width="235" ItemsSource="{Binding}"

SelectionChanged="comboBox1_SelectionChanged" />

<TextBlock Height="36" HorizontalAlignment="Left" Margin="12,120"

Name="textBlock2" Text="Search Topic:" VerticalAlignment="Top" Width="121" />

<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,1,0,0"

Name="textBlock3"

Text="URI:" VerticalAlignment="Top" />

<TextBlock Height="86" HorizontalAlignment="Left" Margin="6,28"

Name="uriTextBlock" TextWrapping="Wrap" Text="{Binding}"

VerticalAlignment="Top" Width="447" />

<TextBlock Height="23" HorizontalAlignment="Left" Margin="12,242,0,0"

Name="textBlock5"

Text="Results:" VerticalAlignment="Top" />

<ListBox Height="352" HorizontalAlignment="Left" Margin="6,271,0,0" Name="listBox1"

VerticalAlignment="Top" Width="444" ItemsSource="{Binding}" >

<ListBox.ItemTemplate>

<DataTemplate>

<Border BorderBrush="{StaticResource PhoneForegroundBrush}" Width="418" BorderThickness="2"

Margin="2">

<StackPanel>

<TextBlock Text="{Binding Path=Title}" TextWrapping="Wrap" />

<TextBlock Text="{Binding Path=Url}" TextWrapping="Wrap"/>

</StackPanel>

</Border>

</DataTemplate>

</ListBox.ItemTemplate>

</ListBox>

</Grid>

</Grid>

</phone:PhoneApplicationPage>

 

C#

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

using Microsoft.Phone.Controls;

using System.Xml.Linq;

 

namespace WindowsPhoneApplication1

{

public partial class MainPage : PhoneApplicationPage

{

// Constructor

String requestString =

"http://api.bing.net/xml.aspx?AppId=’YourAppId’&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict";

string UriNoAppId =

"http://api.bing.net/xml.aspx?AppId=’YourAppId’&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict";

public MainPage()

{

InitializeComponent();

List<string> searchTopics = new List<string>() { "Microsoft", "Silverlight", "Windows Phone 7" };

comboBox1.DataContext = searchTopics;

comboBox1.SelectedIndex = 0;

// Crear el cliente Web y asociar un controlador al evento OpenReadCompleted.

wc = new WebClient();

wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);

}

// Llame al servicio de tema en el sitio de búsqueda Bing.

WebClient wc;

private void CallToWebService()

{

// Llamar a la OpenReadAsyc para hacer una petición GET, pasando la URL con la cadena de búsqueda seleccionados.

wc.OpenReadAsync(new Uri(String.Format(requestString, comboBox1.SelectedItem.ToString())));

}

void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)

{

XElement resultXml;

/ / Siempre se debe comprobar si ha ocurrido un error.

 if (e.Error != null)

{

return;

}

else

{

XNamespace web = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/web";

try

{

resultXml = XElement.Load(e.Result);

/ / Buscar el nodo WebResult y crear un SearchResults objeto para cada uno. var searchResults =

from result in resultXml.Descendants(web + "WebResult")

select new SearchResult

{

/ / Obtener la descripción del título, y los valores Url.

 Title = result.Element(web + "Title").Value,

Description = result.Element(web + "Description").Value,

Url = result.Element(web + "Url").Value

};

/ / Establecer los datos de contexto para el cuadro de lista a los resultados.

listBox1.DataContext = searchResults;

}

catch (System.Xml.XmlException ex)

{

textBlock2.Text = ex.Message;

}

}

}

private void button1_Click(object sender, RoutedEventArgs e)

{

CallToWebService();

}

/ / Actualizar el TextBlock como cambia la selección de cuadro combinado.

private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)

{

uriTextBlock.DataContext = string.Format(UriNoAppId, e.AddedItems[0]);

}

}

// Clase simple que contenga los resultados de búsqueda.

public class SearchResult

{

public string Title { get; set; }

public string Url { get; set; }

public string Description { get; set; }

}

}

 

Detectando la disponibilidad de la red

Para asegurar una buena experiencia de usuario, debes comprobar que el teléfono tiene acceso a Internet antes de llamar a un Servicio Web.  Usas el método NetworkInterface.GetIsNetworkAvailable para determinar si el teléfono tiene conexión a Internet.  Puedes llamar este método antes de llamar al Servicio Web.  Si el método devuelve false, ya sea que pidas al usuario que se conecte a una red viable o hazle saber que la llamada al servicio no pudo ser completada.  Para un ejemplo de cómo utilizar este método, consulta NetworkInterface.GetIsNetworkAvailable.

Nota

La llamada al método NetworkInterface.GetIsNetworkAvailable puede devolver true en el emulador, aun cuando una red no está disponible, por lo que debes probar el código en un dispositivo.