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
- Bien démarrer (Hello World)
- Créer une interface utilisateur pour Windows Phone en XAML
- Utiliser des contrôles
- Types de contrôles
- Contrôles Panorama et Pivot
- Travailler avec du texte sur le Windows Phone
- Mise en page sur l’écran
- Orientations de l’écran
- Saisie tactile
- Navigation
- Exécuter votre application en arrière-plan (tombstoning)
- Notifications Push pour le développement Windows Phone
- Publier votre application sur le Marketplace
Visuels et média
Travailler avec les données
- Obtenir des données dans vos applications Windows Phone
- Data binding
- Isolated storage
- Accéder à un service Web REST
- Consommer des données Windows Azure
Sondes et autres fonctionnalités spécifiques au téléphone
- Lanceurs et choosers
- Détecter des mouvements (accéléromètres)
- Développer avec le GPS Windows Phone (Services de localisation)
- Développer avec l’appareil photo du Windows 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.
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
- <phone:PhoneApplicationPage
- x:Class="WindowsPhoneApplication1.MainPage"
- xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="https://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="https://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="https://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 is the root grid where all page content is placed-->
- <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 contains the name of the application and page title-->
- <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 - place additional content here-->
- <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 =
- "https://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict";
- string UriNoAppId =
- "https://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;
- // Create the WebClient and associate a handler with the OpenReadCompleted event.
- wc = new WebClient();
- wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
- }
- // Call the topic service at the Bing search site.
- WebClient wc;
- private void CallToWebService()
- {
- // Call the OpenReadAsyc to make a get request, passing the url with the selected search string.
- wc.OpenReadAsync(new Uri(String.Format(requestString, comboBox1.SelectedItem.ToString())));
- }
- void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
- {
- XElement resultXml;
- // You should always check to see if an error occurred. In this case, the application
- // simply returns.
- if (e.Error != null)
- {
- return;
- }
- else
- {
- XNamespace web = "https://schemas.microsoft.com/LiveSearch/2008/04/XML/web";
- try
- {
- resultXml = XElement.Load(e.Result);
- // Search for the WebResult node and create a SearchResults object for each one.
- var searchResults =
- from result in resultXml.Descendants(web + "WebResult")
- select new SearchResult
- {
- // Get the Title, Description and Url values.
- Title = result.Element(web + "Title").Value,
- Description = result.Element(web + "Description").Value,
- Url = result.Element(web + "Url").Value
- };
- // Set the data context for the listbox to the results.
- listBox1.DataContext = searchResults;
- }
- catch (System.Xml.XmlException ex)
- {
- textBlock2.Text = ex.Message;
- }
- }
- }
- private void button1_Click(object sender, RoutedEventArgs e)
- {
- CallToWebService();
- }
- // Update the textblock as the combo box selection changes.
- private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- uriTextBlock.DataContext = string.Format(UriNoAppId, e.AddedItems[0]);
- }
- }
- // Simple class to hold the search results.
- public class SearchResult
- {
- public string Title { get; set; }
- public string Url { get; set; }
- public string Description { get; set; }
- }
- }
Visual Basic
- Imports System.Collections.Generic
- Imports System.Linq
- Imports System.Net
- Imports System.Windows
- Imports System.Windows.Controls
- Imports System.Windows.Documents
- Imports System.Windows.Input
- Imports System.Windows.Media
- Imports System.Windows.Media.Animation
- Imports System.Windows.Shapes
- Imports Microsoft.Phone.Controls
- Imports System.Xml.Linq
- Namespace WindowsPhoneApplication1
- Partial Public Class MainPage
- Inherits PhoneApplicationPage
- ' Constructor
- Private requestString As [String] = "https://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict"
- Private UriNoAppId As String = "https://api.bing.net/xml.aspx?AppId='YourAppId'&Query={0}&Sources=Web&Version=2.0&Market=en-us&Adult=Strict"
- Public Sub New()
- InitializeComponent()
- Dim searchTopics As New List(Of String)() From { _
- "Microsoft", _
- "Silverlight", _
- "Windows Phone 7" _
- }
- comboBox1.DataContext = searchTopics
- comboBox1.SelectedIndex = 0
- ' Create the WebClient and associate a handler with the OpenReadCompleted event.
- wc = New WebClient()
- AddHandler wc.OpenReadCompleted, New OpenReadCompletedEventHandler(AddressOf wc_OpenReadCompleted)
- End Sub
- ' Call the topic service at the Bing search site.
- Private wc As WebClient
- Private Sub CallToWebService()
- ' Call the OpenReadAsyc to make a get request, passing the url with the selected search string.
- wc.OpenReadAsync(New Uri([String].Format(requestString, comboBox1.SelectedItem.ToString())))
- End Sub
- Private Sub wc_OpenReadCompleted(sender As Object, e As OpenReadCompletedEventArgs)
- Dim resultXml As XElement
- ' You should always check to see if an error occurred. In this case, the application
- ' simply returns.
- If e.[Error] IsNot Nothing Then
- Return
- Else
- Dim web As XNamespace = "https://schemas.microsoft.com/LiveSearch/2008/04/XML/web"
- Try
- resultXml = XElement.Load(e.Result)
- ' Search for the WebResult node and create a SearchResults object for each one.
- ' Get the Title, Description and Url values.
- Dim searchResults = From result In resultXml.Descendants(web & "WebResult")New SearchResult() With { _
- Key .Title = result.Element(web & "Title").Value, _
- Key .Description = result.Element(web & "Description").Value, _
- Key .Url = result.Element(web & "Url").Value _
- }
- ' Set the data context for the listbox to the results.
- listBox1.DataContext = searchResults
- Catch ex As System.Xml.XmlException
- textBlock2.Text = ex.Message
- End Try
- End If
- End Sub
- Private Sub button1_Click(sender As Object, e As RoutedEventArgs)
- CallToWebService()
- End Sub
- ' Update the textblock as the combo box selection changes.
- Private Sub comboBox1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs)
- uriTextBlock.DataContext = String.Format(UriNoAppId, e.AddedItems(0))
- End Sub
- End Class
- ' Simple class to hold the search results.
- Public Class SearchResult
- Public Property Title() As String
- Get
- Return m_Title
- End Get
- Set(value As String)
- m_Title = Value
- End Set
- End Property
- Private m_Title As String
- Public Property Url() As String
- Get
- Return m_Url
- End Get
- Set(value As String)
- m_Url = Value
- End Set
- End Property
- Private m_Url As String
- Public Property Description() As String
- Get
- Return m_Description
- End Get
- Set(value As String)
- m_Description = Value
- End Set
- End Property
- Private m_Description As String
- End Class
- 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