Publié dimanche 2 mai 2010 00:05 par Audrey

[OData] Utiliser des données OData avec WCF Data Services et Silverlight 4


Comme vu dans un précédent post, OData (Open Data Protocol) est un protocole qui permet d'exposer des données via HTTP, qui se base sur l'architecture REST et qui fournit des données en XML formatées en ATOM ou JSON. WCF Data Services inclus dans Silverlight 4 va nous permettre d'exploiter ces données exposées par OData.

Le but est de faire une application Silverlight 4 de type Maître - Détail avec une ComboBox qui permet de choisir un client et une DataGrid qui permet d'afficher les commandes de ce client. Pour cela, nous allons utiliser les tables Customers et Orders du flux OData de Northwind qui se trouve à cette adresse : http://services.odata.org/Northwind/Northwind.svc/

Voici ce qu'expose le flux OData de Northwind :

OData Northwind

On crée une solution Silverlight 4, et on ajoute au projet Client une référence au service contenant le flux de données OData de Northwind. Pour cela, nous allons utiliser WCF Data Services. Un clic-droit sur le projet Silverlight, puis cliquer sur "Add Service Reference". Une boîte de dialogue apparait et dans le champ "Address", on renseigne l'adresse de notre flux OData mentionné plus haut et on clique sur le bouton "Go" pour vérifier ce qu'expose ce service.

Add Service Reference

Après avoir cliqué sur le bouton "Ok", on peut observer les éléments de notre solution et en afficher les fichiers cachés. On constate que WCF Data Services nous a ajouté 3 nouveaux fichiers :
  • Reference.datasvcmap : qui est un fichier de configuration rassemblant les informations concernant notre service.
  • Reference.cs : qui contient toutes les propriétés et méthodes générées à partir de notre flux.
  • service.edmx : qui contient sous la forme d'un Entity Data Model toutes les informations de notre base de données contenues dans notre flux.
Solution OData

Ensuite on peut construire notre interface en XAML qui va nous permettre d'afficher nos données avec un contrôle ComboBox et un contrôle DataGrid :

<UserControl.Resources>
  <DataTemplate x:Key="DataTemplateComboBoxItelCustomers">
    <TextBlock Text="{Binding ContactName}" />
  </DataTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White" >
  <Grid.RowDefinitions>
    <RowDefinition Height="40" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <ComboBox Grid.Row="0" ItemTemplate="{StaticResource DataTemplateComboBoxItelCustomers}" Name="cbCustomers"     
   SelectionChanged="cbCustomers_SelectionChanged" />

  <sdk:DataGrid AutoGenerateColumns="True" Grid.Row="1" Name="dgOrders" />
</Grid>

Du côté du code-behind, on déclare les membres suivant qui vont nous permettre d'utiliser les données de notre service :

private DataServiceCollection<Customer> _customers;
private DataServiceCollection<Order> _orders;
private Customer _selectedCustomer;
private NorthwindEntities _context;



Puis dans le Loaded de notre User Control, on initialise notre context avec notre service et on initialise les objets qui vont nous permettre de stocker les données concernant les Customers et Orders avec des DataServiceCollection grâce à WCF Data Services. Une requête Linq va sélectionner tous les Customers et les ordonner par leur ContactName. Et enfin on appelle la méthode LoadSync afin de récupérer les données grâce à notre requête Linq :

_context = new NorthwindEntities(new Uri("http://services.odata.org/Northwind/Northwind.svc/"));

_customers = new DataServiceCollection<Customer>();
_customers.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(_customers_LoadCompleted);

_orders = new DataServiceCollection<Order>();
_orders.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(_orders_LoadCompleted);

var query = from g in _context.Customers
            orderby g.ContactName
            select g;
_customers.LoadAsync(query);



Lorsque la méthode LoadAsync est appelée, l'événement LoadCompleted est appelé ce qui va nous permettre de savoir lorsque le chargement des données est terminé afin de binder les données à nos contrôles :

void _customers_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
  if (_customers.Continuation != null)
  {
     _customers.LoadNextPartialSetAsync();
  }
  else
  {
     cbCustomers.ItemsSource = _customers;
     cbCustomers.UpdateLayout();
     cbCustomers.SelectedIndex = 0;
  }
}

void _orders_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
  if (_orders.Continuation != null)
  {
     _orders.LoadNextPartialSetAsync();
  }
  else
  {
     dgOrders.ItemsSource = _orders;
     dgOrders.UpdateLayout();
  }
}



Ensuite dans le SelectionChanged de la ComboBox contenant les Customers, lorsque l'utilisateur choisi un client, son CustomerID va nous servir dans une requête Linq pour sélectionner les commandes lui correspondant. La méthode LoadAsync va nous permettre de charger ses données :

_orders.Clear();
_selectedCustomer = cbCustomers.SelectedItem as Customer;

if (_selectedCustomer != null)
{
   var query = from g in _context.Orders
               where g.CustomerID == _selectedCustomer.CustomerID
               select g;
   _orders.LoadAsync(query);
}



Et voici ce que l'on obtient au final :


Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Les 10 derniers blogs postés

- ProcDump 6.0 : support du filtrage sur messages d'exceptions .NET, des filtres multiples et du ciblage par nom de service par CoqBlog le il y a 22 heures et 57 minutes

- Votez pour le TOP 10 des influenceurs SharePoint francophones ! par Le blog de Patrick [MVP SharePoint] le 05-20-2013, 12:59

- [Conf’SharePoint] Dernier rappel ! :-) par Le blog de Patrick [MVP SharePoint] le 05-20-2013, 09:09

- [ #SharePoint 2013 ] les modèles de sites standards… par Le blog de Patrick [MVP SharePoint] le 05-20-2013, 09:03

- 10 erreurs de compréhension concernant SharePoint… par Le blog de Patrick [MVP SharePoint] le 05-20-2013, 08:27

- Conf’SharePoint : 10 bonnes raisons pour ne pas la rater par Le petit blog de Pierre / Pierre's little blog le 05-14-2013, 02:24

- [Event] Soirée de lancement Agile .NET France à Lyon par Blog Agile/ALM de Vincent THAVONEKHAM le 05-13-2013, 01:29

- .NET / Debug : inspection de la mémoire d'applications .NET (dump ou processus live) : première livraison d'une librairie .NET par Microsoft par CoqBlog le 05-11-2013, 22:21

- SharePoint : Incompatibilité avec Internet Explorer 10 (IE10) par Blog Technique de Romelard Fabrice le 05-08-2013, 16:29

- AutoSPInstaller pour SharePoint 2013 maintenant disponible en “RTM” par Julien Chable le 05-06-2013, 23:30