[SharePoint2010] Introduction à SP2010 pour développeur

Installation d’une machine de développement
Pour installer une machine de développeur, j’ai utilisé la méthode du VHD Boot décrite ici.
Il m’a fallu ensuite installer Visual Studio 2010 béta 2 qui comprend les outils pour le développement SharePoint.
J’ai également installé SharePoint Designer 2010.
Introduction
Après l’installation de SharePoint 2010, on peut découvrir le nouveau design qui rappelle beaucoup celui de la suite office:
L’interface est riche et se rapproche du RIA puisque SP2010 utilise un peu partout l’ajax/javascript et … le Silverlight 3 !
Quel bonheur de voir que dans le menu “Action du site”, la partie More Options est entièrement en Silverlight:
![image101[1]_thumb image101[1]_thumb](http://blogs.dotnet-france.com/juliend/image.axd?picture=image101%5B1%5D_thumb.png)
Des nouvelles technologies clientes, une nouvelle master page, un ribbon qui à fait son apparition… SharePoint 2010 fait peau neuve et fait plaisir à voir.
Il y a une bonne gestion des navigateurs puisque tout au long de me tests j’ai utilisé Chrome© et je n’ai pas trouvé de soucis de compatibilité.
SharePoint “14” a été renommé en deux versions:
- Microsoft SharePoint Server 2010, anciennement MOSS 2007
- Microsoft SharePoint Foundation 2010, anciennement WSS v3
Comme en 2007, SharePoint Server est la version payante qui s’appuie sur la version gratuite SharePoint Foundation lui même basé sur ASP.NET 3.5 SP1 et .NET en général.
A noter l’excellente ressource qu’est le site AreaProg.
SharePoint Designer 2010
SharePoint Designer est un outil type Expression Web qui permet de modifier les pages d’un site SharePoint, créer des petits workflows ou encore administrer quelques parties d’un site.
L’un des principaux défauts de cet outil est dû au fait qu’il ne s’intègre pas dans un cycle de vie de développement et cela devient vite compliqué de réaliser un système de versionning / gestion de code source quand nous l’utilisons.
Cependant il reste bien utile et fait maintenant partie du menu “Site Actions”, ce qui rend son utilisation un peu plus accessible à l’utilisateur lambda.
![image_thumb11[1] image_thumb11[1]](http://blogs.dotnet-france.com/juliend/image.axd?picture=image_thumb11%5B1%5D_thumb.png)
L’apparence a un petit peu changé, SharePoint Designer sera entre autre utile lors de développement de WebPart type XSLT List View.
Premier pas avec Visual Studio 2010
Comme dit précédemment, VS2010 intégre directement les outils pour développer.
Ces outils apportent quelques nouveautés comme le SharePoint Explorer qui s’ajoute au Server Explorer. Ce plug in centralise les informations de votre SharePoint dans Visual Studio.
Un projet sous Visual Studio 2010 se représente de cette manière:
Une des choses nouvelles est le dossier “features” qui représente les features qui vont être déployées. Ce dossier s’accompagne d’un assistant pouvant configurer toutes les features (Les items, les dépendances, le scope…).
Et chose assez pratique, VS2010 attache automatiquement le débuguer au processus W3WP:

Définition de liste et Event Handler
Les listes SharePoint 2010 ont fait des progrès !
Tout d’abord SP2010 est capable d’accueillir des listes de très grande taille. Les listes sont entre autre capable d’avoir une colonne unique, faire des lookup interlistes, gérer l’intégrité des données…
En résumé, on a enfin un vrai model relationnel.
Les Event Handler en SharePoint 2007….
Les event handler sont des événements qui se déclenchent de façon synchrone ou asynchrone. Ce sont un peu comme des Workflows sans interface graphique (ou juste une page d’erreur non personnalisée) et qui effectuent des actions plus simples.
Les événements synchrones démarrent dès que l’action est réalisée et ne rendent la main à l’utilisateur que quand votre code est terminé.
Les événements asynchrones se lancent après que l’action soit réalisée, ils sont non bloquant mais ne permettaient pas d’annuler l’action faite par l’utilisateur.
En SharePoint 2010…
Les event handlers permettent grâce à une classe Synchronization de pouvoir faire un “rollback” avec un événement asynchrone.
Ils sont aussi capable d’afficher une page personnalisée.
De nouveaux événements ont fait leur apparition essentiellement sur les listes de données:
- ListAdding / List Added
- ListDeleting / ListDeleted
Exemple: capter la destruction d’une liste avec l’événement ListDeleting et afficher une page personnalisée.
Un assistant s’ouvre pour vous demander sur quel type d’événements vous souhaitez vous abonner:
On s’abonne à ListDeleting (donc en synchrone) et on va arrêter l’action de suppression:
public override void ListDeleting(SPListEventProperties properties)
{
base.ListDeleting(properties);
properties.Cancel = true;
properties.Status = SPEventReceiverStatus.CancelWithRedirectUrl;
properties.RedirectUrl = "/_layouts/EventReceiverProject2/Error.aspx";
}
On crée la page personnalisée:
Et voilà le résultat:
Développeur Dashboard
Le développeur Dashboard est un outil pour détecter ce qui consomme de la ressource sur votre SharePoint.
On l’active de cette manière (ne pas oublier le IISRESET ensuite):
Et on voit apparaître sur le SharePoint un petit icone:
Lorsqu’on active le dashboard, un panel fait son apparition en bas de page avec un détail sur le temps passé entre chaque appel de fonction, de requêtes ou d’allocations mémoire.
Création d’une webpart
Les Web parts fonctionnement globalement comme en SharePoint 2007.
Il a fait apparition du template Visual WebPart qui n’est ni plus ni moins ce qu’on l’on faisait déjà en SharePoint 2007.
Je ne décrirai pas ici tout ce qui est persistance de données d’une WebPart ou encore les WebParts connectées puisque le code est le même.
Petit exemple malgré tout avec la Visual WebPart, après avoir créé un nouveau projet de type “Visual WebPart” un assistant s’ouvre:

Il faut mettre l’adresse du SharePoint concerné et laissez le choix par défaut, nous y reviendrons plus tard.
Le projet généré est représenté par plusieurs fichiers:
Le fichier Elements.xml qui représente les fichiers embarqués dans la solution et le fichier .webpart qui contient des informations sur la Web Part tels que son titre ou sa description.
VisualWebPart1.cs contient une classe simple qui fait appel à Page.LoadControl pour charger le contrôle utilisateur.
[ToolboxItemAttribute(false)]
public class VisualWebPart1 : WebPart
{
private const string _ascxPath = @"~/_CONTROLTEMPLATES/VisualWebPartProject1/VisualWebPart1/VisualWebPart1UserControl.ascx";
public VisualWebPart1()
{
}
protected override void CreateChildControls()
{
Control control = this.Page.LoadControl(_ascxPath);
Controls.Add(control);
base.CreateChildControls();
}
protected override void RenderContents(HtmlTextWriter writer)
{
base.RenderContents(writer);
}
}
Le fichier ascx représente le code ASP.NET et le .cs son code behind.
Lors de la compilation, un fichier WSP est généré, la feature est déployée et le navigateur s’ouvre sur la création d’une page pouvant accueillir une Web Part.
Il existe aussi les XSLT List View Web Part qui remplace la Data View Web Part de WSS 3.0.
Ce type de webpart, qui affiche des données d’une liste, se fait très facilement avec SharePoint Designer:

Cela fait appel à un contrôle ASP.NET appelé XsltListViewWebPart et qui attend une source de donnée, les champs à afficher et éventuellement une requête de filtrage.
Manipuler le ribbon
Le ribbon importé d’office est l’une des nouveautés qui rend plus ergonomique la navigation dans SharePoint.
Il est possible de le personnaliser par le code.
Exemple: Créer un groupe de contrôles dans le ribbon contenant deux boutons.
On crée un projet vide:
On ajoute un élément vide:
Et on ajoute des balises au fichier Elements.xml. Le but est de créer un groupe de bouton dans l’onglet “List” d’une custom list:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction Id="Ribbon.List.GroupAction"
Location="CommandUI.Ribbon"
RegistrationId="100"
RegistrationType="List">
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition Location="Ribbon.List.Groups._children">
<Group Id="Ribbon.List.MyGroup"
Title="MyGroup"
Template="Ribbon.Templates.Flexible2"
Sequence="10001">
<Controls Id="Ribbon.List.MyGroup.Controls">
<Button Id="Ribbon.List.MyGroup.Button1"
Command="Button1Command"
LabelText="Button1"
TemplateAlias="o1" />
<Button Id="Ribbon.List.MyGroup.Button2"
Command="Button2Command"
LabelText="Button2"
TemplateAlias="o2" />
</Controls>
</Group>
</CommandUIDefinition>
<CommandUIDefinition Location="Ribbon.List.Scaling._children">
<MaxSize Id="Ribbon.List.Scaling.MyGroup.MaxSize"
GroupId="Ribbon.List.MyGroup"
Size="LargeMedium" />
</CommandUIDefinition>
</CommandUIDefinitions>
<CommandUIHandlers>
<CommandUIHandler Command="Button1Command"
CommandAction="" />
<CommandUIHandler Command="Button2Command"
CommandAction="" />
</CommandUIHandlers>
</CommandUIExtension>
</CustomAction>
</Elements>
Reprenons en détail ce code. Dans un premier temps nous déclarons un CustomAction (comme en SharePoint 2007) qui va nous permettre d’aller modifier un des menus.
Nous précisons à ce CustomAction l’ID Ribbon.List.XXX. Cela signale que l’on travaille sur le menu de type ribbon et de son sous menu “List”.
RegistrationId correspond au type de liste sur laquelle on veut voir apparaître le menu (100 = CustomList). RegistrationType applique le menu pour les listes (on aurait pu choisir ContentType, FileType ou ProgId).
La balise CommandUIDefinition contient un groupe de contrôles (deux boutons). Notez la présence de TemplateAlias sur les boutons qui correspond au type d’affichage.
Pour finir les CommandUIHandler permettent de capter les événements, c’est ici qu’on aurait pu lier notre code à une redirection, du code JavaScript ou C#.
Résultat:
Plus d’informations sur les templates, les sous menus, les pages applicatives liées au menu.
Utiliser le dialog framework
Le dialog Framework vous donne la possibilité de créer des fenêtres JavaScript modales de ce type:

Pour cela plusieurs options, entres autres celle de déclencher du JavaScript dans le CommandAction d’un bouton du ribbon.
On reprend donc l’exemple fait précédemment et on implémente le clic sur le bouton.
Pour cela on ajoute déjà une page à notre projet (Add->New item sur le projet):
Et c’est cette page que l’on va vouloir afficher dans une modal popup.
<CommandUIHandler Command="Button2Command"
CommandAction="javascript:
function Callback(dialogResult, returnValue)
{
SP.UI.Notify.addNotification('Popup fermée');
}
var options = {
url: '/_layouts/RibbonTest/MaPage.aspx',
title: 'Custom Dialog Box',
allowMaximize: false,
showClose: true,
width: 400,
height: 400,
dialogReturnValueCallback: Callback };
SP.UI.ModalDialog.showModalDialog(options); " />
On aurait aussi pu utiliser la méthode RefreshPage pour rafraichir les données de la liste.
Le callback sert à afficher une petite notification à l’utilisateur à la fermeture de la popup:
La Status Bar
Le status bar est utilisable comme les notifications grâce au JavaScript.
SP.UI.Status.addStatus('Popup fermée');
A noter que l’on peut changer la couleur avec la méthode setStatusPriColor ou encore modifier le status avec updateStatus et le supprimer avec removeStatus.
Linq To SharePoint
Linq To SharePoint ou SPLinq est un outil de requêtage qui offre une alternative à la génération à la main de requête CAML avec SPQuery (limité au contexte du serveur).
On connait déjà les avantages de Linq, facile d’utilisation, vérification à la compilation des erreurs, IntelliSense, une seule et même façon de requêter des données (SQL, XML…)…
Note: SPLinq ne remplace pas SPSiteDataQuery qui permet de réaliser des requêtes sur tout une collection de sites.
SPLinq utilise donc la syntaxe de Linq pour générer des requêtes CAML.
Comme Linq-To-SQL qui utilise SQLMetal, là on utilisera SPMetal pour générer un model par rapport à un site SharePoint.
Cette commande nous génère un fichier Model.cs qu’il faut ensuite incorporer à notre projet.
Ce fichier contient le context de données de votre SharePoint comme par exemple les listes personnalisées.
Pour utiliser SPLinq, le projet doit aussi référencer la dll Microsoft.SharePoint.Linq et utiliser ces espaces de noms:
using Microsoft.SharePoint.Linq;
using System.Linq;

Pour illustrer mon exemple, j’avais créé une première liste “entreprise” et une liste “commandes":
protected void ClickMe(object sender, EventArgs e)
{
ModelDataContext context = new ModelDataContext(SPContext.Current.Web.Url);
EntityList<CommandesItem> commandes =
context.GetList<CommandesItem>("Commandes");
var query = from commande in commandes
where commande.Entreprise.Title.Equals("DOLLON")
select commande;
spGridView.DataSource = query;
spGridView.DataBind();
}
Pour connaître le CAML généré, vous pouvez utiliser cette méthode.
Comme les autres providers Linq, SPLinq propose de manipuler les données de façon CRUD (Create, Read, Update, Delete).
Nous avons vu “read” ci-dessus, passons au reste:
Comme pour l’Entity Framework, la création se passe avec l’instanciation d’une nouvelle entité, l’appel à la méthode Insert et l’envoi du “commit” avec la méthode SubmitChanges();
ModelDataContext context = new ModelDataContext(SPContext.Current.Web.Url);
EntityList<ClientsItem> clients = context.GetList<ClientsItem>("Clients");
ClientsItem client = new ClientsItem();
client.Entreprise = "Exakis2";
client.Title = "DOLLON2";
clients.InsertOnSubmit(client);
context.SubmitChanges();
Pensez à gérer les exceptions de type conflits ou duplication.
La mise à jour se fait en retrouvant l’entité concernée et en modifiant ses attributs.
ModelDataContext context = new ModelDataContext(SPContext.Current.Web.Url);
EntityList<ClientsItem> clients = context.GetList<ClientsItem>("Clients");
var client = (from cl in clients
where cl.Title.Equals("DOLLON2")
select cl).First();
client.Title = "VALENTIN";
context.SubmitChanges();
Pour la suppression, il y a deux moyens. Le premier étant de retrouver l’entité concernée comme pour la modification et effectuer la suppression. Cette méthode n’est pas conseillée car elle vous impose de charger toute l’entité avant de la supprimer. Ce qui peut se révéler particulièrement lourd si vous avez à supprimer des milliers de lignes.
Le second moyen est de retrouver seulement l’ID de la personne à supprimer. Exemple:
ModelDataContext context = new ModelDataContext(SPContext.Current.Web.Url);
EntityList<ClientsItem> clients = context.GetList<ClientsItem>("Clients");
var id = (from cl in clients
where cl.Title.Equals("VALENTIN")
select cl.Id).First();
ClientsItem client = new ClientsItem();
client.Id = id;
context.Clients.Attach(client);
context.Clients.DeleteOnSubmit(client);
context.SubmitChanges();
Le Client Object Model pour CLR.NET
Le Client OM est un outil pour développeur permettant d’accéder aux modèles objet de SharePoint (SPServer, SPFarm…).
Ce modèle contenu dans la dll Microsoft.SharePoint.Client.dll est décliné en plusieurs versions telle que pour la clr .NET, Silverlight mais aussi JavaScript.
Dans ce chapitre nous aborderons la version .NET en créant une petite application WPF qui travaillera sur un SharePoint distant.
Vous noterez la simplicité d’utilisation comparée à l’utilisation des Web Services de SharePoint 2010 où il fallait formater un fichier XML à envoyer au serveur pour modifier un élément d’une liste.
Voici un récapitulatif des “armes” à disposition du développeur pour utiliser les objets SP:
Voilà comment fonctionne le Client Object Model (toujours en rouge le côté client et en vert le côté serveur):

Important à préciser que le Client OM fonctionne à partir du framework 3.5. Il est donc utilisable dans de nombreux projets (Winforms, WPF, Office, Application console, service WCF…).
La DLL se trouve dans le dossier ISAP:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI
On crée un projet WPF et on y ajoute ces deux références:
![image_thumb21[1] image_thumb21[1]](http://blogs.dotnet-france.com/juliend/image.axd?picture=image_thumb21%5B1%5D.png)
using Microsoft.SharePoint.Client;
using SP = Microsoft.SharePoint.Client;
L’interface graphique de notre projet ressemble à ça:
Le but étant d’implémenter les boutons en traitant la liste Clients vue dans un chapitre précédent.
Le premier bouton qui charge une liste possède ce code:
ClientContext context = new ClientContext("http://localhost");
SP.List clients = context.Web.Lists.GetByTitle("Clients");
SP.ListItemCollection myItems = clients.GetItems(new CamlQuery());
//context.Load(clients);
context.Load(myItems);
context.ExecuteQuery();
lst.ItemsSource = myItems;
lst.DisplayMemberPath = "[Title]";
Explication en détail de ce code:
ClientContext permet de se connecter au SharePoint distant, je récupère ensuite la liste concernée ainsi que ses items (remarquez que je passe une requête CAML vide, nous y reviendrons).
La méthode Load sert à charger l’objet, puis ExecuteQuery envoie toutes les requêtes d’un coup au service SharePoint.
Après l’accès aux éléments de la liste, passons au tri grâce à plusieurs moyen:
SP.ListItemCollection myItems = clients.GetItems(new CamlQuery()
{
ViewXml = @"<View>
<Query>
<Where>
<Neq>
<FieldRef Name='Title' />
<Value Type='Text'>DOLLON</Value>
</Neq>
</Where>
</Query>
</View>"
});
- LoadQuery & Mot clé Where
context.Load(myItems, items => items.Include(item => item["Title"]).Where(item => (string)item["Title"] != "DOLLON"));
context.ExecuteQuery();
Cette requête affichera tous les éléments exceptés ceux qui s’appellent “DOLLON”. L’appel à la méthode Include permet de charger l’index Title et la méthode Where réalise une comparaison.
Nous aurions pu utiliser la méthode LoadQuery à la place de Load dans cet exemple.
Pour finir, parlons de CRUD. Comment se passe l’ajout, modification et suppression ? Et bien de cette manière simple (comme en SP2007):
myItems[0]["Title"] = "Heliot";
myItems[0].Update();
context.ExecuteQuery();
Silverlight & SharePoint
Silverlight est présent un peu partout dans SharePoint 2010. Déjà à travers d’une WebPart spécialement conçue pour ça:
![image_thumb[8] image_thumb[8]](http://blogs.dotnet-france.com/juliend/image.axd?picture=image_thumb%5B8%5D.png)
Ainsi qu’une Silverlight Media WebPart en créant ce type de liste:
Mais aussi par le fait que Silverlight possède également sa propre version du Client OM (et peut être enfin interopérable avec les services SharePoint Restfull). Les DLL se trouvent dans le dossier 14:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin
Comme à son habitude, les méthodes du proxy sont faites en asynchrones.
Les librairies pèsent respectivement 262ko et 138ko, pensez donc à activer l’assembly caching :)
Pour illustrer le Client OM sous Silverlight, je vais développer une webpart en Silverlight 3.0.
Après avoir créé un nouveau projet Silverlight et référencé les DLL, j’implémente ce code permettant d’interroger une liste:
private ListItemCollection items;
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
var context = SP.ClientContext.Current;
var web = context.Web;
var list = web.Lists.GetByTitle("Clients");
items = list.GetItems(new CamlQuery());
context.Load(list);
context.Load(items);
context.ExecuteQueryAsync(succeededCallBack, failedCallback);
}
private void failedCallback(object sender, ClientRequestFailedEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Erreur " + args.Message);
});
}
private void succeededCallBack(object sender, ClientRequestSucceededEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
foreach (var item in items)
MessageBox.Show(item["Title"].ToString());
});
}
Ensuite je crée un projet vide SharePoint avec un module pour ajouter le fichier .xap à mon SharePoint ou tout simplement en créant un dossier ClientBin dans le dossier web de SharePoint pour y mettre mon fichier .xap.
Je l’héberge ensuite avec la webpart Silverlight et tout ceci fonctionne.
Notez qu’il est possible d’activer le debugueur Silverlight d’après la présentation de la PDC.
JavaScript & SharePoint
Il existe de même un client OM en JavaScript. Comme pour Silverlight il utilise des méthodes asynchrones pour appeler le service.
Plusieurs scripts sont nécessaires:
- SP.js 380ko
- SP.Core.js 13ko
- SP.Runtime.js 68ko
Ces scripts sont intégrables en utilisant la balise:
<SharePoint:ScriptLink runat="server" Name="sp.js"/>
Un article est à venir sur l’utilisation de cette API avec jQuery.
Les SharePoint REST Services
Pour communiquer avec SharePoint nous avons plusieurs possibilités comme vue précédemment.
L’une d’entre elles est d’utiliser l’architecture REST mise en place pour accéder aux données.
Petit rappel sur REST, c’est un terme pour désigner une source de données accessible grâce au protocole HTTP de manière CRUD (Create, Read, Update, Delete).
L’API Rest est basée sur WCF Data Services (aussi appelé Astoria 1.5), on peut donc accéder aux données au format ATOM ou JSON (donc compatible Silverlight & Ajax) de cette manière:
http://url_du_site/_vti_bin/ListData.svc/Nom_liste
Avec la possibilité que propose Astoria c’est à dire les filtres dans l’URL, le trie…
On peut attaquer directement en ajoutant une référence dans Visual Studio au service listdata.svc.
Les applications “sandboxées”
Chapitre à venir sous peu
Nouveautés des workflows
Chapitre à venir sous peu
SharePoint BCS
Chapitre à venir sous peu