• Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Consommer des données OData

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

OData (Open Data Protocol) est un protocole permettant le partage de données. Aujourd’hui, il y a beaucoup de données un peu partout sur internet et sous diverses formes. Lorsqu’elles sont dans des formats propriétaires, elles deviennent difficiles à exploiter. Le but de ce protocole est de fournir un moyen standardisé d’effectuer des requêtes sur ces données grâce aux protocoles standards du web dans l’optique d’améliorer l’accès à ces données et d’augmenter l’interopérabilité.
Les applications Windows Phone peuvent tirer parti d’OData grâce à une bibliothèque qui s’occupe d’encapsuler tous les appels et tout le système de requêtage. Comme d’habitude, un proxy est généré avec des classes représentant le modèle de données. Les requêtes REST sont encapsulées et les données seront exploitables grâce à LINQ.

Ajouter une référence service

De plus en plus de données sont accessibles au format OData. Vous pouvez retrouver beaucoup de fournisseurs de données OData sur le site officiel. Pour illustrer la récupération de données avec OData, j’ai choisi d’exploiter la base de questions-réponses de l’excellent site Stack Overflow. Le flux OData est disponible à cette adresse : http://data.stackexchange.com/stackoverflow/atom.
Lorsque nous naviguons sur ce lien, nous récupérons un flux XML qui contient à vue de nez des questions (Posts), des utilisateurs (Users), des Tags,…

Pour pouvoir exploiter ces données, la première chose à faire est d’ajouter une référence de service et de saisir l’adresse de notre flux OData :

Image utilisateur

Visual Studio génère alors le proxy et les classes qui vont permettre de récupérer ces données, elles sont dans l’espace de nom que nous avons donné, à savoir StackOverflowReference :

Image utilisateur

Charger les données

Nous allons pouvoir utiliser ces classes désormais. La première chose à faire est d’indiquer au service l’url du flux OData :

Entities service = new Entities(new Uri("http://data.stackexchange.com/stackoverflow/atom"));

Ensuite, nous allons pouvoir écrire une requête LINQ. Ici par exemple, je souhaite obtenir la liste des utilisateurs triés par réputation :

IQueryable<User> requete = from utilisateur in service.Users
                                orderby utilisateur.Reputation descending
                                select utilisateur;

J’écris une simple requête LINQ. Ce qui est magique c’est qu’elle sera transformée automatiquement en requête REST, sans rien de plus à faire.
Maintenant, je dois préparer le chargement asynchrone des données. Pour cela, j’ai besoin de la classe générique DataServiceCollection<>. C’est elle qui, via sa méthode LoadAsync, va me remplir mon objet. Pour voir les effets du chargement, je vais lier l’objet qui récupère les données à une ListBox, pour cela je déclare ma propriété ainsi, comme nous l’avons déjà fait :

private DataServiceCollection<User> utilisateurs;
public DataServiceCollection<User> Utilisateurs
{
    get
    {
        return utilisateurs;
    }
    set
    {
        if (value == utilisateurs)
            return;
        utilisateurs = value;
        NotifyPropertyChanged("Utilisateurs");
    }
}

Il ne restera plus qu’à démarrer le chargement, avec :

Utilisateurs = new DataServiceCollection<User>();
Utilisateurs.LoadAsync(requete.Take(10));

Ici, j’ai choisi de n’afficher que les dix premiers éléments de la liste. Au final, nous aurons donc le code suivant :

public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
{
    private DataServiceCollection<User> utilisateurs;
    public DataServiceCollection<User> Utilisateurs
    {
        get
        {
            return utilisateurs;
        }
        set
        {
            if (value == utilisateurs)
                return;
            utilisateurs = value;
            NotifyPropertyChanged("Utilisateurs");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string nomPropriete)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(nomPropriete));
    }

    public MainPage()
    {
        InitializeComponent();

        DataContext = this;

        Entities service = new Entities(new Uri("http://data.stackexchange.com/stackoverflow/atom"));

        IQueryable<User> requete = from utilisateur in service.Users
                                    orderby utilisateur.Reputation descending
                                    select utilisateur;


        Utilisateurs = new DataServiceCollection<User>();
        Utilisateurs.LoadAsync(requete.Take(10));
    }
}

À noter qu’on peut s’abonner à un événement pour savoir quand les données ont été récupérées. Ce n’est pas utile ici, mais cela pourrait être intéressant si l’on souhaite afficher que le chargement est en cours, mettre une barre de progression, ...
Il ne reste qu’à écrire le XAML de la ListBox afin d’exploiter nos données :

<ListBox ItemsSource="{Binding Utilisateurs}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid Width="480">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding DisplayName}" />
                <TextBlock Grid.Column="1" Text="{Binding Reputation}" />
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Remarquez que j’exploite directement les données de l’objet User avec notamment les propriétés DisplayName et Reputation.

Ce qui donne :

Image utilisateur

Faire des requêtes sur les données

Et voilà, nous avons pu faire une requête OData très facilement grâce à LINQ. Toute la complexité a été masquée, mais remarquons quand même que le proxy a en fait exécuté la requête suivante :

Citation

http://data.stackexchange.com/stackoverflow/atom/Users()?$orderby=Reputation desc&$top=10

La requête générée est la base de l’interrogation des données au format OData. Même si le format de la requête est un peu particulier, on voit bien qu’on demande la liste des utilisateurs, triés par réputation descendante, et on récupère le top 10.
C’est ça qu’il se passe à chaque fois derrière. LINQ va générer une requête HTTP sous la forme d’une requête REST qui nous permettra d’obtenir les informations que l’on souhaite.

En fait, avant la version 7.1 du SDK, il fallait faire tout ceci à la main. C’est devenu très simple à faire désormais comme vous pouvez vous en rendre compte. Les données OData sont à notre portée, il n’y a plus qu’à les exploiter. :D

En résumé
  • Pour récupérer des données OData, on utilise une référence de service qui génère un proxy.

  • Ce proxy masque toute la complexité permettant d’interroger la ressource REST.

  • La bibliothèque OData pour Windows Phone permet, grâce à LINQ, de générer les requêtes adéquates pour la récupération des données.

Exemple de certificat de réussite
Exemple de certificat de réussite