Sharepoint 2010 propose 2 nouveaux modèles d’accès aux données côté client:
Dans cet article, nous nous focaliserons sur la deuxième solution.
Il y a de nombreux avantages à utiliser OData pour accéder à vos données :
Voici un tutoriel qui vous montre comment utiliser OData dans une application Silverlight, pour manipuler une liste Sharepoint.
Le tutoriel peut s’appliquer à n’importe quelle liste d’un site Sharepoint 2010 sauf une liste externe. Pour le tutoriel j’utiliserai une liste appelée Wines d’un site CaveAVins. Cette liste possède 2 colonnes :
Les étapes de ce tutoriel sont les suivantes:
Notez qu’en Silverlight, l’exécution des requêtes s’effectuera forcément de manière asynchrone ce qui complique légèrement le code.
Créez une nouvelle application Silverlight nommée SlSpOData et cliquez Ok.
Conservez les attributs par défaut dans l’écran du wizard et cliquez Ok.
Vous obtenez 2 projets :
Dans le projet SlSpOData, nous allons ajouter une référence au service WCF listdata.svc qui correspond au site contenant votre liste. Faites un click droit sur les références du projet SlSpOData, puis choisissez “Add Service Reference”.
Dans notre exemple, le site utilisé est : http://stephe-msft/Demos/CaveAVins. Suffixez l’adresse par /vti_bin/listdata.svc pour accéder au service WCF implémentant l’accès OData pour ce site. Dans mon cas, j’obtiens http://stephe-msft/Demos/CaveAVins/_vti_bin/listdata.svc
Collez cette URL dans un navigateur web, et vérifiez que vous obtenez bien un flux xml. Si vous obtenez l’erreur Impossible de charger le type System.Data.Services.Providers.IDataServiceUpdateProvider, allez voir ce post qui résoudra votre problème.
Renseignez ensuite cette adresse dans le champ Adresse du wizard et cliquez Go:
Des classes proxy correspondant au modèle de votre site vont être générées pour vous simplifier leur manipulation par le code. Le nom de la classe principale qui contiendra nos listes Sharepoint sous forme de propriétés apparait dans la zone “services”. Ici, c’est une classe nommée CaveAVinsDataContext ( “NomSite”DataContext). Modifions le namespace dans lequel sera définie cette classe et appelons le “CaveAVinsService”.
Cliquez Ok.
Ouvrez le fichier MainPage.xaml pour y ajouter le contrôle de type ListBox qui affichera la liste Sharepoint Wines. Ajoutez les lignes suivantes dans la grid:
<ListBox x:Name="lbWines" ItemsSource="{Binding}">
</ListBox>
Ce code permet de déclarer une liste nommée lbWines dont la source de données sera le DataContext (qui lui sera affecté plus tard par code-behind)
Modifiez à présent la manière de représenter chacun des éléments de la liste en redéfinissant l’ItemTemplate de la ListBox :
une zone de texte attachée à la colonne Title
une zone de texte attachée à la colonne Count
<ListBox x:Name="lbWines" ItemsSource="{Binding}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Title}" Margin="10" ></TextBlock> <TextBlock Text="{Binding Count}" Margin="10" ></TextBlock> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Le code complet suivant de la page devrait ressembler à ceci:
<UserControl x:Class="SlSpOData.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <ListBox x:Name="lbWines" ItemsSource="{Binding}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Title}" Margin="10" ></TextBlock> <TextBlock Text="{Binding Count}" Margin="10" ></TextBlock> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid></UserControl>
Passez maintenant dans le code-behind de la page MainPage.xaml.cs. Voici le code par défaut de votre page:
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; namespace SlSpOData{ public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } }}
Ajoutons une méthode “LoadWines” qui va récupérer les items de la liste des vins en utilisant les classes proxy générées. On instancie le contexte CaveAVinsDataContext en passant en paramètre l’adresse du service. On utilise Linq pour récupérer tous les éléments de la liste des vins triée par nombre de bouteilles.
Chaque liste du site CaveAVins est matérialisée par une propriété dans la classe CaveAVinsDataContext et une classe proxy a été générée pour représenter un élément de la liste Wines. Dans notre cas, nous y trouvons la propriété DataServiceQuery<WinesItem> Wines. L’exécution de la requête se fait en asynchrone en Silverlight, c’est pourquoi on repasse la main au thread du dispatcher pour affecter le résultat de la requête au DataContext de la ListBox.
CaveAVinsDataContext dc = new CaveAVinsDataContext(new Uri(http://stephe-msft/Demos/CaveAVins/_vti_bin/listdata.svc));
void LoadWines(){ var query = dc.Wines.OrderBy(w => w.Count) as DataServiceQuery<WinesItem>; query.BeginExecute( asyncResult => Dispatcher.BeginInvoke(() => { lbWines.DataContext = query.EndExecute(asyncResult); }) , null );}
Voici le code complet de la classe avec l’appel à LoadWines dans le constructeur de la page :
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 SlSpOData.CaveAVinsService;using System.Data.Services.Client; namespace SlSpOData{ public partial class MainPage : UserControl { CaveAVinsDataContext dc = new CaveAVinsDataContext(new Uri(http://stephe-msft/Demos/CaveAVins/_vti_bin/listdata.svc)); public MainPage() { InitializeComponent(); LoadWines(); } void LoadWines() { var query = dc.Wines.OrderBy(w => w.Count) as DataServiceQuery<WinesItem>; query.BeginExecute( asyncResult => Dispatcher.BeginInvoke(() => { lbWines.DataContext = query.EndExecute(asyncResult); }) , null ); } }}
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 SlSpOData.CaveAVinsService;using System.Data.Services.Client; namespace SlSpOData{ public partial class MainPage : UserControl {
public MainPage() { InitializeComponent(); LoadWines(); } void LoadWines() { var query = dc.Wines.OrderBy(w => w.Count) as DataServiceQuery<WinesItem>; query.BeginExecute( asyncResult => Dispatcher.BeginInvoke(() => { lbWines.DataContext = query.EndExecute(asyncResult); }) , null ); } }}
Exécutez l’application, voici le résultat:
Nous allons instancier un nouvel élément et sauvegarder les changements dans Sharepoint. Dans la classe CaveAVinsDataContext, la méthode AddToWines est là pour nous simplifier le travail. Il suffit ensuite de sauvegarder les changements (toujours en asynchrone):
void AddWine() { WinesItem newWine = new WinesItem() { Title = "Champagne", Count = 1 }; dc.AddToWines(newWine); dc.BeginSaveChanges( (IAsyncResult result) => dc.EndSaveChanges(result), null); }
Vous pouvez modifier le constructeur de la classe pour appeler la méthode AddWine avant LoadWines et vous verrez le champagne apparaitre en tête de liste à l’exécution.
public MainPage() { InitializeComponent(); AddWine(); LoadWines(); }
Vous pouvez également supprimer un élément de la liste en appelant dc.DeleteObject en passant en paramètre une instance de WinesItem à supprimer, de la manière suivante:
void DeleteWines(WinesItem wine) { dc.DeleteObject(wine); dc.BeginSaveChanges( (IAsyncResult result) => dc.EndSaveChanges(result) , null); }
Grâce aux classes proxy, il est très facile de passer par OData pour intégrer et manipuler nos listes Sharepoint dans une application. Ce tutoriel met en œuvre une application Silverlight mais le protocole OData peut être utilisé sur toute plateforme supportant http ce qui permet d’ouvrir l’accès aux données de Sharepoint à une grande variété de technos clientes.
Vive le vin, vive le vin, vive le vin d'hiver...
Salut Stéphanie,
Il me semble que vous étiez aux Microsoft Days 2010 de Aix-en-Provence, où nous vous avons vue lors d'une démonstration, Livoy (CLUB INTERNET Olivier G.) & Moi.
Nous avons trouvé super votre projet de cave à vin mais n'avons pas encore le niveau, je vous remercie de nous répondre par un simple commentaire pour nous assurer de vous avoir bien identifiée afin de poursuivre nos projets.
Merci beaucoup,
Cordialement,
PS: nous étions au rang des speakers.
Bonjour,
Oui c'est bien moi que vous avez vue aux MsDays
Contente que cela vous ait intéressé :)