Centre de développement Sharepoint 2010
Sharepoint 2010 - MSDN
Tutoriels Sharepoint 2010 sur areaprog
Developper Top 10 Resource Center | Sharepoint
A l’occasion de l’annonce d’ Office 365, un tout nouveau centre de ressources est lancé. Il est dédié au développement sur Sharepoint Online.
Vous y trouverez toutes sortes de ressources spécifiques à la version Online de Sharepoint : articles, blogs, webcasts,Channel9…
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.
Le hub Sharepoint c’est bien, mais développer ses propres applications Windows Phone 7 qui accèdent à Sharepoint, c’est encore mieux (pour un développeur en tout cas ) !
Le plus difficile dans l’histoire, c’est l’authentification entre votre application et Sharepoint. La suite reste un développement tout à fait classique d’une application Silverlight (à la mode Metro près ) présentant des données de Sharepoint.
Voici un article de Paul Stubbs qui vous explique comment vous authentifier à Sharepoint à partir d’une application Silverlight pour Windows Phone 7.
Un nouveau blog technique très intéressant pour les développeurs Sharepoint : Sharepoint in Pictures
Vous y trouverez un nouvel article chaque semaine en mode “Picture Driven” c’est à dire que le fond de l’article sera présenté sous forme d’image plutôt que sous forme textuelle. Plus sympa et explicite qu’un gros pavé de texte: une super initiative !
Xavier Vanneste a publié une bêta sur CodePlex qui permet d’afficher vos listes Sharepoint sous la forme d'un Pivot Viewer (toutes les infos sur son blog).
Pour vous donner une petite idée du rendu:
J’en profite pour relayer un exemple d’implémentation d’un PivotViewer basé sur des données dans Azure (par Eric Vernié) . Voilà qui vous permettra de jouer avec cette techno “en vrai” et vous mettra vraisemblablement l’eau à la bouche .