Developpement Windows Phone - partie 22

Cet article fait partie d’une série d’articles sur le développement Windows Phone. Il s’agit d’une traduction des articles se trouvant sur la MSDN.

Sommaire

Bien débuter et fondamentaux

Visuels et média

Travailler avec les données

Sondes et autres fonctionnalités spécifiques au téléphone


Accéder à un Web Service REST

Representational State Transfer (REST) fait référence à un style d’architecture pour exposer des ressources sur le web pouvant être accédées par des clients. De nombreuses ressources, comme les blogs, les cartes, les produits sont exposés en tant que service REST sur le Web. Silverlight fournit des classes qui rendent très simple l’appel à des services REST depuis une application Windows Phone. Ce tutoriel explique comment appeler et travailler avec des services REST.

Ce tutoriel contient les sections suivantes :

Note

Les exemples fournis dans ce guide de démarrage s’exécutent dans le navigateur pour simuler le comportement de Silverlight sur Windows Phone. Le comportement réel peut être légèrement différent dans le simulateur Windows Phone ou sur le téléphone lui-même.

 

Consommer un Service REST

Les appels aux services REST se fait un utilisant les verbes standards HTTP (GET, POST, PUT, et DELETE). Les ressources sont identifiées par une URI. Une réponse contient une représentation, habituellement en XML ou JavaScript Object Notation (JSON), de la ressource spécifiée. Les requêtes sont sans états (stateless), ce qui signifie que toutes les informations nécessaire à l’exécution de la requête doivent être inclues dans chaque requête.

Un aspect important de l’appel de services REST est de s’assurer que l’URI correcte est utilisée lorsque vous tentez d’accéder à une ressource. La plupart du temps les compagnies fournissent une liste des prérequis d’un appel, contenant les paramètres et les valeurs qui doivent être passées. Par exemple, pour appeler le web service Bing, vous pouvez vous référer au Bing API guidelines.

Silverlight pour Windows Phone fournit plusieurs classes pour consommer des services REST. Il faut toutefois garder à l’esprit que Windows Phone utilise Silverlight 3, ce qui implique que les fonctions de réseau de Silverlight 4 ne sont pas disponibles pour les clients Windows Phone. Pour plus d’information sur les différentes de fonctionnalités réseau entre Silverlight pour Windows Phone et Silverlight pour Windows, jetez un œil à Networking in Silverlight for Windows Phone.

Pour consommer un service REST depuis une application cliente Windows Phone, vous pouvez soit utiliser la classe WebClient ou les classes HttpWebRequest/HttpWebResponse. Avec ces deux options, les requêtes sont asynchrones. Toutefois, WebClient est le plus simple des deux.

WebClient utilise un système simple basé sur des évènements pour faire des requêtes et en récupérer les réponses. Pour utiliser WebClient, vous devez appeler la méthode Async appropriée et vous abonner à l’évènement Completed correspondant. Le tableau ci-dessous contient quelques-unes des méthodes et évènements de WebClient que vous pouvez utiliser, en fonction de l’action et du type de donnée.

Action

Type de Donnée

Méthodes et évènements

GET

String

Méthode DownloadStringAsync Evènement DownloadStringCompleted

GET

Stream

Méthode OpenReadAsync Evènement OpenReadCompleted

POST

String

Méthode UploadStringAsync Evènement UploadStringCompleted

POST

Stream

Méthode OpenWriteAsync Evènement OpenWriteCompleted

La classe HttpWebRequest vous permet d’avoir un plus grand contrôle sur le message de la requête, tel que les messages HTTP PUT et DELETE. Pour plus d’information sur l’utilisation des classes the HttpWebRequest/HttpWebResponse , jetez un œil à la classe HttpWebRequest.

 

Exemple d’appel de Service REST

L’exemple ci-dessous illustre l’usage de la classe WebClient pour envoyer une requête depuis une application Windows Phone vers le service de recherche Bing. Dans cet exemple, vous pouvez changer le texte recherché en utilisant la liste déroulante, ce qui met à jour l’URI de recherche. Lorsque vous cliquez sur le bouton Search! , une requête est envoyée au service de recherché Bing. En plus du texte recherché, l’URI utilisée contient l’information indiquant que le résultat de la requête doit être au format XML. Les résultats sont parsés et affichés dans la liste.

Get Microsoft Silverlight

Note

Bien que cet exemple contienne un Bing Application ID dans l’URI pour effectuer la requête, l’Application ID utilisé n’est pas affiché dans le code. Pour obtenir un Application ID servant à utiliser le service de recherche Bing, allez voir Getting Started with Bing Api Version 2.

Note sur la sécurité

Lorsque vous vous connectez à un service web qui nécessite une clef, ne stockez pas cette clef dans l’application qui s’exécutera sur un téléphone. À la place, créez un web service proxy qui identifiera l’utilisateur et appellera le service externe avec la clef. Pour plus d’information sur les recommandations de sécurité, jetez un œil à Web Service Security for Windows Phone.

Vous trouverez ci-dessous le markup et le code de cet exemple.

 

XAML

  1. <phone:PhoneApplicationPage
  2.             x:Class="WindowsPhoneApplication1.MainPage"
  3.             xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4.             xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  5.             xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  6.             xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  7.             xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
  8.             xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
  9.             mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
  10.             FontFamily="{StaticResource PhoneFontFamilyNormal}"
  11.             FontSize="{StaticResource PhoneFontSizeNormal}"
  12.             Foreground="{StaticResource PhoneForegroundBrush}"
  13.             SupportedOrientations="Portrait" Orientation="Portrait"
  14.             shell:SystemTray.IsVisible="False">
  15.     <!--LayoutRoot is the root grid where all page content is placed-->
  16.     <Grid x:Name="LayoutRoot" Background="Transparent">
  17.         <Grid.Resources>
  18.             <Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem" >
  19.                 <Setter Property="Foreground" Value="Black"/>
  20.                 <Setter Property="Background" Value="LightGray"/>
  21.             </Style>
  22.             <Style x:Key="ComboBoxStyle" TargetType="ComboBox" >
  23.                 <Setter Property="Foreground" Value="Black"/>
  24.                 <Setter Property="Background" Value="Gray"/>
  25.             </Style>
  26.         </Grid.Resources>
  27.         <Grid.RowDefinitions>
  28.             <RowDefinition Height="Auto"/>
  29.             <RowDefinition Height="*"/>
  30.         </Grid.RowDefinitions>
  31.         <!--TitlePanel contains the name of the application and page title-->
  32.         <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
  33.             <TextBlock x:Name="ApplicationTitle" Text="REST CLIENT"
  34.                        Style="{StaticResource PhoneTextNormalStyle}"/>
  35.             <TextBlock x:Name="PageTitle" Text="bing search"
  36.                        Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"
  37.                        Height="99" Width="453" />
  38.         </StackPanel>
  39.         <!--ContentPanel - place additional content here-->
  40.         <Grid x:Name="ContentPanel" Margin="12,139,12,0" Grid.RowSpan="2">
  41.             <Button Content="Search!" Height="89" HorizontalAlignment="Left"
  42.                     Margin="264,140,0,0" Name="button1"
  43.                     VerticalAlignment="Top" Width="189" Click="button1_Click" />
  44.             <ComboBox Height="50" Style="{StaticResource ComboBoxStyle}"
  45.                       HorizontalAlignment="Left" Margin="6,159" Name="comboBox1"
  46.                       ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
  47.                       VerticalAlignment="Top" Width="235" ItemsSource="{Binding}"
  48.                       SelectionChanged="comboBox1_SelectionChanged" />
  49.             <TextBlock Height="36" HorizontalAlignment="Left" Margin="12,120"
  50.                        Name="textBlock2" Text="Search Topic:" VerticalAlignment="Top" Width="121" />
  51.             <TextBlock Height="23" HorizontalAlignment="Left" Margin="12,1,0,0"
  52.                        Name="textBlock3"
  53.                        Text="URI:" VerticalAlignment="Top" />
  54.             <TextBlock Height="86" HorizontalAlignment="Left" Margin="6,28"
  55.                        Name="uriTextBlock" TextWrapping="Wrap" Text="{Binding}"
  56.                        VerticalAlignment="Top" Width="447" />
  57.             <TextBlock Height="23" HorizontalAlignment="Left" Margin="12,242,0,0"
  58.                        Name="textBlock5"
  59.                        Text="Results:" VerticalAlignment="Top" />
  60.             <ListBox Height="352" HorizontalAlignment="Left" Margin="6,271,0,0" Name="listBox1"
  61.                      VerticalAlignment="Top" Width="444" ItemsSource="{Binding}" >
  62.                 <ListBox.ItemTemplate>
  63.                     <DataTemplate>
  64.                         <Border BorderBrush="{StaticResource PhoneForegroundBrush}" Width="418" BorderThickness="2"
  65.                                 Margin="2">
  66.                             <StackPanel>
  67.                                 <TextBlock Text="{Binding Path=Title}" TextWrapping="Wrap" />
  68.                                 <TextBlock Text="{Binding Path=Url}" TextWrapping="Wrap"/>
  69.                             </StackPanel>
  70.                         </Border>
  71.                     </DataTemplate>
  72.                 </ListBox.ItemTemplate>
  73.             </ListBox>
  74.         </Grid>
  75.     </Grid>
  76. </phone:PhoneApplicationPage>

C#

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Documents;
  8. using System.Windows.Input;
  9. using System.Windows.Media;
  10. using System.Windows.Media.Animation;
  11. using System.Windows.Shapes;
  12. using Microsoft.Phone.Controls;
  13. using System.Xml.Linq;
  14. namespace WindowsPhoneApplication1
  15. {
  16.     public partial class MainPage : PhoneApplicationPage
  17.     {
  18.         // Constructor
  19.         String requestString =
  20.         "https://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict";
  21.         string UriNoAppId =
  22.         "https://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict";
  23.         public MainPage()
  24.         {
  25.             InitializeComponent();
  26.             List<string> searchTopics = new List<string>() { "Microsoft", "Silverlight", "Windows Phone 7" };
  27.             comboBox1.DataContext = searchTopics;
  28.             comboBox1.SelectedIndex = 0;
  29.             // Create the WebClient and associate a handler with the OpenReadCompleted event.
  30.             wc = new WebClient();
  31.             wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
  32.         }
  33.         // Call the topic service at the Bing search site.
  34.         WebClient wc;
  35.         private void CallToWebService()
  36.         {
  37.             // Call the OpenReadAsyc to make a get request, passing the url with the selected search string.
  38.             wc.OpenReadAsync(new Uri(String.Format(requestString, comboBox1.SelectedItem.ToString())));
  39.         }
  40.         void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
  41.         {
  42.             XElement resultXml;
  43.             // You should always check to see if an error occurred. In this case, the application
  44.             // simply returns.
  45.             if (e.Error != null)
  46.             {
  47.                 return;
  48.             }
  49.             else
  50.             {
  51.                 XNamespace web = "https://schemas.microsoft.com/LiveSearch/2008/04/XML/web";
  52.                 try
  53.                 {
  54.                     resultXml = XElement.Load(e.Result);
  55.                     // Search for the WebResult node and create a SearchResults object for each one.
  56.                     var searchResults =
  57.                     from result in resultXml.Descendants(web + "WebResult")
  58.                     select new SearchResult
  59.                     {
  60.                         // Get the Title, Description and Url values.
  61.                         Title = result.Element(web + "Title").Value,
  62.                         Description = result.Element(web + "Description").Value,
  63.                         Url = result.Element(web + "Url").Value
  64.                     };
  65.                     // Set the data context for the listbox to the results.
  66.                     listBox1.DataContext = searchResults;
  67.                 }
  68.                 catch (System.Xml.XmlException ex)
  69.                 {
  70.                     textBlock2.Text = ex.Message;
  71.                 }
  72.             }
  73.         }
  74.         private void button1_Click(object sender, RoutedEventArgs e)
  75.         {
  76.             CallToWebService();
  77.         }
  78.         // Update the textblock as the combo box selection changes.
  79.         private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
  80.         {
  81.             uriTextBlock.DataContext = string.Format(UriNoAppId, e.AddedItems[0]);
  82.         }
  83.     }
  84.     // Simple class to hold the search results.
  85.     public class SearchResult
  86.     {
  87.         public string Title { get; set; }
  88.         public string Url { get; set; }
  89.         public string Description { get; set; }
  90.     }
  91. }

Visual Basic

  1. Imports System.Collections.Generic
  2. Imports System.Linq
  3. Imports System.Net
  4. Imports System.Windows
  5. Imports System.Windows.Controls
  6. Imports System.Windows.Documents
  7. Imports System.Windows.Input
  8. Imports System.Windows.Media
  9. Imports System.Windows.Media.Animation
  10. Imports System.Windows.Shapes
  11. Imports Microsoft.Phone.Controls
  12. Imports System.Xml.Linq
  13. Namespace WindowsPhoneApplication1
  14.     Partial Public Class MainPage
  15.         Inherits PhoneApplicationPage
  16.         ' Constructor
  17.         Private requestString As [String] = "https://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict"
  18.         Private UriNoAppId As String = "https://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict"
  19.         Public Sub New()
  20.             InitializeComponent()
  21.             Dim searchTopics As New List(Of String)() From { _
  22.             "Microsoft", _
  23.             "Silverlight", _
  24.             "Windows Phone 7" _
  25.             }
  26.             comboBox1.DataContext = searchTopics
  27.             comboBox1.SelectedIndex = 0
  28.             ' Create the WebClient and associate a handler with the OpenReadCompleted event.
  29.             wc = New WebClient()
  30.             AddHandler wc.OpenReadCompleted, New OpenReadCompletedEventHandler(AddressOf wc_OpenReadCompleted)
  31.         End Sub
  32.         ' Call the topic service at the Bing search site.
  33.         Private wc As WebClient
  34.         Private Sub CallToWebService()
  35.             ' Call the OpenReadAsyc to make a get request, passing the url with the selected search string.
  36.             wc.OpenReadAsync(New Uri([String].Format(requestString, comboBox1.SelectedItem.ToString())))
  37.         End Sub
  38.         Private Sub wc_OpenReadCompleted(sender As Object, e As OpenReadCompletedEventArgs)
  39.             Dim resultXml As XElement
  40.             ' You should always check to see if an error occurred. In this case, the application
  41.             ' simply returns.
  42.             If e.[Error] IsNot Nothing Then
  43.                 Return
  44.             Else
  45.                 Dim web As XNamespace = "https://schemas.microsoft.com/LiveSearch/2008/04/XML/web"
  46.                 Try
  47.                     resultXml = XElement.Load(e.Result)
  48.                     ' Search for the WebResult node and create a SearchResults object for each one.
  49.                     ' Get the Title, Description and Url values.
  50. Dim searchResults = From result In resultXml.Descendants(web & "WebResult")New SearchResult() With { _
  51. Key .Title = result.Element(web & "Title").Value, _
  52. Key .Description = result.Element(web & "Description").Value, _
  53. Key .Url = result.Element(web & "Url").Value _
  54. }
  55.                     ' Set the data context for the listbox to the results.
  56.                     listBox1.DataContext = searchResults
  57.                 Catch ex As System.Xml.XmlException
  58.                     textBlock2.Text = ex.Message
  59.                 End Try
  60.             End If
  61.         End Sub
  62.         Private Sub button1_Click(sender As Object, e As RoutedEventArgs)
  63.             CallToWebService()
  64.         End Sub
  65.         ' Update the textblock as the combo box selection changes.
  66.         Private Sub comboBox1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
  67.             uriTextBlock.DataContext = String.Format(UriNoAppId, e.AddedItems(0))
  68.         End Sub
  69.     End Class
  70.     ' Simple class to hold the search results.
  71.     Public Class SearchResult
  72.         Public Property Title() As String
  73.             Get
  74.                 Return m_Title
  75.             End Get
  76.             Set(value As String)
  77.                 m_Title = Value
  78.             End Set
  79.         End Property
  80.         Private m_Title As String
  81.         Public Property Url() As String
  82.             Get
  83.                 Return m_Url
  84.             End Get
  85.             Set(value As String)
  86.                 m_Url = Value
  87.             End Set
  88.         End Property
  89.         Private m_Url As String
  90.         Public Property Description() As String
  91.             Get
  92.                 Return m_Description
  93.             End Get
  94.             Set(value As String)
  95.                 m_Description = Value
  96.             End Set
  97.         End Property
  98.         Private m_Description As String
  99.     End Class
  100. End Namespace

 

Détecter la connectivité réseau

Pour obtenir une bonne expérience utilisateur, vous devez vérifier que le téléphone dispose d’une connexion à Internet avant de tenter un appel de service web. Vous pouvez utiliser la méthode NetworkInterface.GetIsNetworkAvailable pour connaitre l’état de la connexion à Internet. Si le retour est la valeur false, vous devrez alors soit afficher un message à l’utilisateur pour lui demander de se connecter à un réseau, ou informer l’utilisateur que les appels aux services web ne peuvent être effectués. Pour un exemple d’utilisation de cette méthode, jetez un œil à NetworkInterface.GetIsNetworkAvailable.

Note

Un appel à la méthode NetworkInterface.GetIsNetworkAvailable peut retourner la valeur true sur l’émulateur même si aucune connectivité n’est disponible, vous devrez donc tester votre code sur un téléphone.

A Voir

 


Cliquez ici pour revenir au sommaire de la liste d’articles