Outils

[SP2013-SP2016] – Utiliser un JSLink pour afficher un slider

Posted on Updated on

Bonjour à tous,

Cela fait un moment que je n’ai rien publié, mais j’ai été pas mal occupé 🙂

Aujourd’hui, comment créer un jslink qui affichera les images d’une bibliothèque d’image sous forme de Slideshow en JavaScript en utilisant les jslink.

1/ Créer une bibliothèque d’images et ajouter des images

Première étape donc, créer une bibliothèque d’image dans un site SharePoint. Facilement réalisable, à la souris via l’interface de création des applications. Pour cela, rendez-vous sur votre site SharePoint concerné, puis utilisez l’engrenage (Paramètres / Settings), puis créer une Application (Add an app) :

01

 

Puis sélectionner le type d’application “Bibliothèque d’images” (Picture Library) :

02

 

Ici je l’appellerai “Images” pour cet exemple :

03

 

L’application “Images” de type bibliothèque d’images est créée :

04

 

Ensuite, je vais charger un ensemble d’images que je souhaite afficher dans mon slideshow. Pour cela, j’utilise le site Pexels (https://www.pexels.com/) mais vous pourrez en trouver sur beaucoup de sites (Attention au droit à l’image) :

05

 

Puis je les télécharger dans SharePoint (via glisser-déposer, mais pour pouvez évidemment utiliser le bouton télécharger, Windows Explorer etc.) :

06

 

Mes images sont donc maintenant dans SharePoint.

 

2/ Les ressources nécessaires

Afin que le diaporama soit animé, et de ne pas redévelopper la roue, j’ai choisi d’utiliser un JavaScript bien connu afin de créer mon diaporama qui s’appelle slidejs (http://www.slidesjs.com/). Ce script est assez facile d’utilisation, il est responsive, “touchable” (tablettes, smartphones) et utilise CSS3 (attention aux navigateurs non-compatibles… ça existe encore).

Il peut également démarrer tout seul (auto-play), utilise des transitions etc. Tout ceci peut être personnalisé suivant les besoins. Ici, je voudrai qu’il change de photo seulement quand l’utilisateur clique sur le bouton suivant (ou précédent).

Je vais donc avoir besoin de charger JQuery, et jquery.slides.min.js.

Pour ma part, JQuery est chargé dans la masterpage de mon site (et le fichier est dans le hive car je l’utilise sur tous les sites : /template/layouts/demo/jquery-1.11.2.min.js) :

07

Et dans ma masterpage (je vous laisse voir les différents moyens de charger JQuery) :

<SharePoint:ScriptLink ID="ScriptLink6" language="javascript"  Name="/_layouts/15/demo/jquery-1.11.2.min.js" runat="server" Localizable="false"/>;

08

 

Pour la fichier jquery.slides.min.js, je vais le charger dans la bibliothèque de style de la collection de sites car il n’est utilisé que pour ce site, et pas sur les autres (rien ne vous empêche de le déployer dans le hive). Pour cela :

Accéder au contenu du site racine (qui est le site en question dans mon exemple), utilisez l’engrenage puis “Contenu du site” (Site Content) :

09

Puis accédez à l’application “Style Library” :

10

Dans cette application, je créé un nouveau répertoire pour isoler mes ressources, ce répertoire s’appellera “demo” :

11

12

13

Et enfin je télécharger le fichier “jquery.slides.min.js” dans ce nouveau répertoire :

14

 

Sans oublier de l’archiver puis de le publier :15

16

17

Et enfin, il nous faut télécharger dans ce même répertoire le fichier JSLink permettant de lancer le Slideshow. Nous allons voir maintenant ce qu’il contient…

3/ Le JSLink

Ici nous allons donc utiliser le fichier “SharePointSlideshow.js” (vous pourrez bien sûr le renommer).

Premièrement, nous allons déclarer un namespace spécifique :

Type.registerNamespace('DEMO');
DEMO.SPSlideshow = DEMO.SPSlideshow || {};
DEMO.SPSlideshow.Templates = DEMO.SPSlideshow.Templates || {}
DEMO.SPSlideshow.Functions = DEMO.SPSlideshow.Functions || {}

Puis déclarer un ID global pour le div qui encapsulera les éléments du slideshow :

var slideshowId = '';

Et enfin, déclarer les fonctions nécessaires :

Fonction affichant 1 élement :

DEMO.SPSlideshow.Functions.Display = function (ctxSlideshow) {

    var viewMoreLabel = "+ Read more";    
    var webpartTitle = "";

    /* DECLARE COLUMNS INTERNAL NAMES  */
    var ColumnIDInternalName = "ID";
    var ColumnTitleInternalName = "Title";
    var ColumnFileRefInternalName = "FileRef";   
    
    /* GET ITEM VALUES FROM CONTEXT  */
    var item = ctxSlideshow.CurrentItem;
    var itemId = item[ColumnIDInternalName];
    var itemTitle = item[ColumnTitleInternalName];
    var itemFileUrl = item[ColumnFileRefInternalName];
       
    //create img form jsslide library
    var strSlideshow = '<img src="' + itemFileUrl + '">';
    
    return strSlideshow;
}

Fonction générant le Header (div encapsulant la structure générale, voir documentation de slidejs) :

DEMO.SPSlideshow.Functions.GenerateHeader = function (ctxSlideshow) {

    var webpartId = ctxSlideshow.wpq;
    var webpartTitleCell = '#WebPartTitle' + webpartId;
    $("#WebPart" + webpartId).css("position","relative");
    var header = '<div class="container">';
    slideshowId = 'slides' + ctxSlideshow.ctxId;
    header += '<div id="' + slideshowId + '">';
    //insert buttons for next and previous
    header += '<a href="#" id="slideshowleftarrow" class="slidesjs-previous slidesjs-navigation"></a>';
    header += '<a href="#" id="slideshowrightarrow" class="slidesjs-next slidesjs-navigation"></a>';
    return header;
}

Fonction générant le Footer (div fermant la structure générale, voir documentation de slidejs):

DEMO.SPSlideshow.Functions.GenerateFooter = function (ctxSlideshow) {  
    var footer = '</div>';
    footer += '</div>';
    return footer;
}

Fonction permettant d’appliquer les éléments en JQuery sur la structure, et mettant en forme le slideshow :

DEMO.SPSlideshow.Functions.PostRender = function (ctxSlideshow) {   
    //start slide
    $(function () {
        var slidedivid = '#' + slideshowId;
        $(slidedivid).slidesjs({
            start: 2,
            pagination: {
                active: false
            }       
        });
    });    
}

Et enfin, le bout de script permettant de faire le “register” du JSLink sur le WebPart standard d’affichage des images (Application Picture Library) :

DEMO.SPSlideshow.Templates.RegisterSlideshowDisplay = function () {
// Fallback to loading jQuery from a CDN path if the local is unavailable
(window.jQuery || document.write('&lt;script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.11.2.min.js"&gt;&lt;\/script&gt;'));

var slideshowcontext = {};
slideshowcontext.Templates = {};
slideshowcontext.Templates.Header = DEMO.SPSlideshow.Functions.GenerateHeader;
slideshowcontext.Templates.Item = DEMO.SPSlideshow.Functions.Display;
slideshowcontext.Templates.Footer = DEMO.SPSlideshow.Functions.GenerateFooter;
slideshowcontext.Templates.OnPostRender = DEMO.SPSlideshow.Functions.PostRender;

slideshowcontext.ListTemplateType = 109;
slideshowcontext.BaseViewID = 6;

SPClientTemplates.TemplateManager.RegisterTemplateOverrides(slideshowcontext);
}

//Register CSR-MDS module then call template registration
DEMO.SPSlideshow.Functions.RegisterInMDS = function () {
//RegisterLikes-override for MDS disabled site (because we need to call the entry point function in this case whereas it is not needed for anonymous functions)
ExecuteOrDelayUntilScriptLoaded(DEMO.SPSlideshow.Templates.RegisterSlideshowDisplay, 'clienttemplates.js');
// RegisterLikes-override for MDS enabled site
RegisterModuleInit(_spPageContextInfo.siteServerRelativeUrl + "/Style Library/demo/SharePointSlideshow.js", DEMO.SPSlideshow.Templates.RegisterSlideshowDisplay);
}

//Load CSR-MDS module if feature is activated
if (typeof _spPageContextInfo != "undefined" &amp;&amp; _spPageContextInfo != null) {
DEMO.SPSlideshow.Functions.RegisterInMDS();
}
else {
ExecuteOrDelayUntilScriptLoaded(DEMO.SPSlideshow.Templates.RegisterSlideshowDisplay, 'clienttemplates.js');
}

Lorsque ce fichier est globalement (et syntaxiquement ok), il faut le télécharger avec le fichier précédent dans Style Library/Demo (on l’archive et publie également) :

18

 

4/ Utilisation

Pour utiliser ce JSLink, il faut tout d’abord ajouter le composant WebPart de l’application Picture Library sur une page. La page d’accueil par exemple. On édite la page en cliquant sur le bouton Modifier (Edit) dans le coin haut-droit :

19

Dans la galerie de WebParts, on choisit le WebPart associé à la nouvelle application Bibliothèque d’images (qui s’appelait “Images” dans mon cas) :

20

 

Et on l’ajoute dans la page, puis on sauvegarde la page :21

Ensuite, on repasse en édition sur la page, et on modifie les propriétés du composant WebPart que l’on vient d’ajouter :

19

Dans le coin en haut à droite du WebPart, on accède au menu “Modifier le composant WebPart” (Edit Web Part) :

22

 

La “boite à outils” du WebPart s’ouvre sur la droite :

23

Dans le dernier champ “JS Link”, il faut indiquer le chemin (relatif à la collection de sites) vers le fichier “SharePointSlideshow.js”. Dans mon cas, j’indique :

~sitecollection/Style%20Library/demo/jquery.slides.min.js|~sitecollection/Style%20Library/demo/SharePointSlideshow.js

J’utilise le token “~sitecollection” afin d’indiquer que mon url est relative à la collection de site (vous pouvez également utiliser ~site), SharePoint se chargera de recomposer l’url absolue. Et ensuite, j’utilise “|” afin de dire à SharePoint qu’il doit charger 2 scripts : “jquery.slides.min.js” et “SharePointSlideshow.js” :

24

 

On clique sur “OK”, on enregistre et immédiatement, le slideshow est fonctionnel (moche mais fonctionnel). En effet les boutons “Previous” et “Next” fonctionnement :

25 26

 

5/ Faire du beau…

En effet, le rendu est un peu sommaire… des liens cliquables, en bas… pas super ergonomique et même moche. Allez on fait du “un peu plus beau”. Et donc de la CSS !

Premièrement, je vais utiliser 4 images pour remplacer les liens Previous / Next par des flèches qui changeront de couleur lorsque la souris les survolera :

rightarrow-active rightarrow-inactive leftarrow-active leftarrow-inactive

 

 

Je vais télécharger ces images dans l’application “Style Library, dans le même dossier que les fichiers *.js téléchargés précédemment :

27

 

Puis enfin je vais créer une nouvelle feuille de style qui contiendra quelques directives pour mettre en place tout ça qui s’appellera SharePointSlideshow.css. Je choisis également de la déployer dans l’application Style Library et de la référencer dans la masterpage :

28

Dans la masterpage :

<SharePoint:CssRegistration ID="DemoCSS" Name="<% $SPUrl:~sitecollection/Style Library/demo/SharePointSlideshow.css %>" After="corev15.css" runat="server">

29

 

Et enfin le contenu de la CSS :

/* WebPart slideshow */

#slideshowleftarrow{
background:url('/sites/tests/Style%20Library/demo/leftarrow-inactive.png');
background-repeat:no-repeat;
height: 46px;
width: 35px;
position:absolute;
top:50%;
left:0;
z-index:98;

}

#slideshowrightarrow{
background:url('/sites/tests/Style%20Library/demo/rightarrow-inactive.png');
background-repeat:no-repeat;
height: 46px;
width: 35px;
position:absolute;
top:50%;
right:0;
z-index:98;

}

#slideshowleftarrow:hover{
background:url('/sites/tests/Style%20Library/demo/leftarrow-active.png');
background-repeat:no-repeat;
height: 46px;
width: 35px;
position:absolute;
top:50%;
left:0;
z-index:99;

}
#slideshowrightarrow:hover{
background:url('/sites/tests/Style%20Library/demo/rightarrow-active.png');
background-repeat:no-repeat;
height: 46px;
width: 35px;
position:absolute;
top:50%;
right:0;
z-index:99;

}

a[title="Previous"] {
display:none;
}

a[title="Next"] {
display:none;
}

/* End WebPart slideshow */

 

Et voici le résultat :

slideshowjs

 

 

[Azure] – Créer une ferme SharePoint avec Microsoft Azure

Posted on Updated on

 

Bonjour à tous.

Une fois n’est pas coutume, cet article ne traitera pas directement de SharePoint mais de la création d’une ferme SharePoint dans Microsoft Azure. En effet, grâce aux abonnements MSDN proposés gratuitement aux MCT, ou via un partenariat entre votre société et Microsoft, il vous est peut être possible d’accéder gratuitement à la plateforme Azure.

C’est mon cas grâce au MCT (Microsoft Certified Trainer). Microsoft me propose gratuitement d’utiliser Azure dans la limite de 100$/mois, voire plus suivant le type de MCT choisi lors du renouvellement par exemple. Un peu plus d’information ici (en anglais) : http://pages.email.microsoftemail.com/page.aspx?QS=38dfbe491fab00ea2a47f1ea8bd86c9a9fbfdac1c1554482f65d74c18d68d0fb&ArticleID=659e3777-a52a-46ab-834e-49a0a3110561

Première chose à faire : activer votre compte Azure dans le portail MSDN.

 

1/ Activation de votre abonnement Azure

Pour cela, il vous faudra vous rendre sur http://msdn.microsoft.com/. Il vous faut ensuite vous identifier avec votre compte Live associé à votre abonnement, puis cliquer sur le lien en haut à droite sur “MSDN Subscriptions” :

01

Puis vous devrez sans doute vous identifier de nouveau. Dans la page proposée ensuite, cliquez sur “Activate Microsoft Azure” :

02

Remplissez ensuite le formulaire proposé. A noter que Microsoft propose de vous envoyer ensuite un SMS avec un code d’identification. Notez également qu’aucun numéro de carte bleue n’est demandé (c’est rassurant…).

Puis Validez le formulaire. Vous recevrez un e-mail de confirmation sur la boite e-mail associée à votre compte Live. Cet e-mail contient un lien vers le portail de gestion de votre abonnement Azure (il est également proposé à la fin de l’inscription).

NB : Attention, l’activation de votre compte peut prendre quelques minutes, Cliquez sur “Click here to refresh” jusqu’à ce que la ligne disparaisse. Votre abonnement sera activé !

03

Nous pouvons maintenant passer à la configuration de notre ferme SharePoint dans Azure !

 

2/ Nouvelle console de gestion Azure

Le lien proposé dans l’e-mail ou à la fin de l’inscription vous renvoie vers l’ancienne version de la console de gestion Azure. Pour utiliser la nouvelle version, cliquez sur votre nom (depuis l’ancien portail) et cliquez sur le lien “Switch to new portail”. Vous sera alors déconnecté et vous devrez vous identifier sur le nouveau portail :

04

Ce nouveau portail ressemble à cela, beaucoup plus sympa comme style… :

05

 

3/ Création de la ferme SharePoint – Azure

Cette console va nous aider à créer notre environnement SharePoint. Pour cela nous allons cliquer sur le bouton “+” en bas à gauche puis sur “Everything” en haut à droite :

06

Nous allons retrouver dans la liste tous les environnements proposés dans Azure. On clique ensuite sur Virtual Machines :

07

Il suffit ensuite de parcourir la liste et de choisir “SharePoint Server Farm” et de cliquer sur “Create” :

08

Un assistant démarre ensuite et va nous aider à configurer notre future ferme. Il vous demande de compléter :

  • Resource Group : groupe de ressources pour la gestion de l’environnement
  • User Name : nom d’utilisateur pour l’administrateur du domaine / ferme SharePoint. Il faut ici mettre un compte (nouveau) et non votre compte Live
  • Password / Confirm Password : un mot de passe complexe

09

La coche Enable High Availability permet d’installer une ferme gérant la haute disponibilité et multiplie les serveurs. Dans mon cas, c’est une ferme de démo, donc je ne choisis pas de l’activer.

Puis on clique sur la section “DOMAIN CONTROLLERS” et on complète :

  • Host Name Prefix : par défaut = SharePoint. Je conserve.
  • Forest root domaine name : par défaut : contoso.com. Je modifie avec un nom de forêt personnalisé.
  • Pricing Tier : plan de facturation / ressources systèmes associé. Vous pouvez choisir entre A1 Basic ou A1 Standard, leur prix étant proche (attention on ne paie pas, c’est retranché sur votre quota).

Pour distinguer les deux plans… et d’autres (il y en a une bonne douzaine) :

A1 Basic A1 Standard A2 Standard
1 core 1 core 2 cores
1.75GB 1.75GB 3,5GB
2 Data disks 2 Data disks 4 Data disks
600 IOPS 1000 IOPS 2000 IOPS
Load Balancing Load Balancing
Autoscale Autoscale
24,38€/mois 33,24€/mois 66,49€/mois

 

Dans mon cas, j’ai choisi A1 Basic :

10

La section DOMAIN CONTROLLERS est configurée :

11

 

On clique sur la section en dessous : SQL SERVERS :

Nous allons configurer le compte de service pour SQL Server, le plan de facturation des serveurs SQL / Performances.

Je choisi ici de ne pas utiliser le même password que le compte administrateur et un plan A1 Basic :

12

Puis on passe à la section SHAREPOINT SERVERS :

13

 

On configure les comptes nécessaires pour l’installation de SharePoint et le Farm Account de notre ferme SharePoint. Je choisis ici un plan Standard A2 (conseillé) :

14

¨Puis nous pouvons configurer des paramétrages optionnels comme les Virtual Networks, Storage Account et Diagnostics :

15

J’ai conservé par défaut la section Virtual Network :

16

Pour la partie Storage Account, j’ai créé un nouveau compte :

17

Puis j’ai configuré la partie Diagnostics en standard :

18

 

On peut ensuite éventuellement changer de plan de souscription ou de localisation pour les données (pour moi Europe du Nord) :

20

 

Puis on clique sur “CREATE”.

NB le fait de conserver la coche “Add to Stardboard” sélectionnée vous permet d’avoir une tuile sur le tableau de bord (affichage en live… ) :

21

 

Sur la gauche, dans les notifications, une barre de progression nous indique l’état d’avancement général :

image

On patiente…

On patiente…

On patiente…

Une erreur peut être affichée… on recharge la page si besoin :

image

Et après une quinzaine / trentaine de minutes la ferme est bien créée :

24

 

On peut voir le détail des machines / comptes / configurations en cliquant sur “2 more…” :

25

4/ Se connecter à la ferme SharePoint

Cela peut paraitre un peu étonnant ou surprenant au départ, mais pour vous connecter à votre serveur SharePoint, il vous faudra accéder à l’écran précédent, cliquer sur Virtual Machine et sélectionner votre machine SharePoint.  Dans l’écran de droite, vous allez pouvoir gérer votre machine virtuelle : Démarrer, redémarrer, arrêter, supprimer… et vous connecter. Il suffit de cliquer sur CONNECT et de télécharger le fichier RDP proposé. Puis on double-clic sur ce fichier.

26

27

Il vous faudra entrer les identifiants et mots de passe entrés lors de la configuration des machines. Dans mon cas le compte administrateur de la ferme SharePoint :

28

 

Par contre, je m’attendais à ce que tout soit configuré… et j’ai donc lancé la console d’administration centrale de SharePoint. Surprise, on me dit que l’Assistant de Configuration de la ferme n’a pas encore été lancé. Il faut donc le faire manuellement :

29

 

5/ Finir l’installation de SharePoint Server 2013

Je le démarre donc à partir de cette fenêtre :

30

Il faut donc dérouler toute l’installation et la configuration à partir du PSConfig :

31

33

 

Et voilà !

34

[SharePoint 2013] – Installation des Office Web Apps 2013 avec SharePoint Server 2013

Posted on Updated on

 

Bonjour à tous.

Un nouvel article pour vous montrer comment installer et configurer les Office Web Apps 2013 couplées à SharePoint Server 2013.

Pour l’histoire, les Office Web Apps sont arrivées dans leur deuxième version : nous avons les Office Web Apps 2010 et 2013 à ce jour. Ces OWA vont nous permettre, couplées à SharePoint, d’ouvrir des documents Word, Excel, PowerPoint et OneNote directement dans le navigateur, sans utiliser les composants clients Office. Ce qui peut être évidemment très pratique lors les collaborateurs utilisent des plateformes hétérogènes de types tablettes iPad, Android, des téléphones mobiles ou encore des postes de travail sous MacOS ou une distribution Linux.

Il faut bien intégrer pour commencer qu’à chaque version de SharePoint correspond une version des Office Web Apps :

  • SharePoint 2010 (Foundation ou Server) => Office Web Apps 2010
  • SharePoint 2013 (Foundation ou Server) => Office Web Apps 2013

Coté Licencing, vous pourrez installer ces OWA (2010 ou 2013) suivant le type de licences que vous possédez pour le pack Office. Si vous possédez les packs Office (en volumes) version 2010 vous pourrez éditer les fichiers Office. Si vous ne les possédez pas, vous pourrez seulement lire des documents Office via les OWA.

 

De plus, avec la version 2010 des OWA, il était possible d’installer ce composant logiciel sur le même serveur que le serveur SharePoint (en le boostant un peu…). Avec la version 2013, ce n’est plus possible et ces composants s’installe sur un serveur dédié, rattaché au même domaine que SharePoint. Il y a quelques contraintes supplémentaires comme de ne pas avoir installé le pack Office sur ce serveur. Pour plus de renseignements : http://technet.microsoft.com/fr-fr/library/jj219458.aspx

 

Pour l’architecture utilisée pour cet article, j’ai 3 machines virtuelles (VM) :

  • 1 contrôleur de domaine : DOMAIN
  • 1 serveur SharePoint Server 2013 Enterprise (EN) : SP2013-DEV
  • 1 serveur Office Web Apps 2013 : SPOWA2013

Ces trois serveurs sont rattachés au même domaine : DEMO, sont installés sous Windows Server 2012 ou Windows Server 2008R2 (EN) et à jour :

 

image

Et oui… une belle débauche de mémoire et de processeurs… Sourire

 

Je précise que mes machines Active Directory & SharePoint étaient déjà installées et fonctionnelles avant l’installation d’Office Web Apps.

Première étape installer et configurer Windows Server 2012 (et mettre à jour !), je ne détaillerai pas cela dans cet article.

 

1/ Préparation du serveur pour Office Web Apps 2013

 

Lorsque le serveur a été installé et configuré, il faut commencer par télécharger les Office Web Apps 2013. Pour cela, vous pouvez télécharger la Preview ici : http://www.microsoft.com/en-us/download/details.aspx?id=30358 ou ici http://www.microsoft.com/fr-fr/download/details.aspx?id=35489. Vous pourrez également télécharger l’iso depuis votre compte MSDN ou Technet.

 

Connectez vous ensuite à votre serveur OWA avec un compte du domaine qui est administrateur local du serveur (dans mon cas, c’est le même que le compte d’installation de SharePoint : DEMO\spadmin).

 

Il faut ensuite exécuter un script PowerShell sur le serveur OWA en lançant la commande en administrateur. Pour cela, rendez-vous sur les “tuiles” de Windows Server 2012, repérez la tuile Windows PowerShell :

image

 

Faites un clic-droit sur la tuile :

image

 

Et cliquez sur “Run as administrator” :

image

 

Vous pouvez avoir l’UAC qui se déclenche, on clique sur “Yes” :

image

 

Et PowerShell 3.0 :

image

 

Nous allons lancer un script permettant d’installer et de configurer les rôles et services nécessaires sur le serveur pour OWA 2013. Vous trouverez des informations complémentaires ici : http://technet.microsoft.com/fr-fr/library/jj219455.aspx.

On copie / colle le script :

 

Add-WindowsFeature Web-Server,Web-Mgmt-Tools,Web-Mgmt-Console,Web-WebServer,Web-Common-Http,Web-Default-Doc,Web-Static-Content,Web-Performance,Web-Stat-Compression,Web-Dyn-Compression,Web-Security,Web-Filtering,Web-Windows-Auth,Web-App-Dev,Web-Net-Ext45,Web-Asp-Net45,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Includes,InkandHandwritingServices

 

Le script d’installation se lance et devrait durer… moins de 3 minutes :

image

 

Mais que fait ce script me direz-vous ? Il se charge d’installer le rôle Web Server de Windows Server 2012 (installer IIS), et active sur ce rôle les différents protocoles, utilitaires qu’utiliseront les OWA 2013.

Lorsque le script est terminé, redémarrer le serveur OWA 2013. En allant dans le gestionnaire du serveur, on voit tout de suite le nouveau rôle IIS qui apparait :

 

image

 

image

 

Les extensions et fonctionnalités activées :

image

 

2/ Installation des Office Web Apps 2013

 

Maintenant que les prérequis sont installés, il va falloir installer les binaires des Office Web Apps 2013. Pour cela il faut monter l’iso téléchargé précédemment sur la machine virtuelle et lancer le setup d’installation :

image

 

Pour cela, on se rend dans l’explorateur de fichier et on fait un clic-droit sur le lecteur DVD avec l’iso monté, puis “Install or run program from your media” (s’il ne démarre pas tout seul).

Encore une fois, l’UAC peut s’activer, on clique sur “Yes” :

image

 

Le contrat de licence apparait, on sélectionne la case à cocher en bas, puis on clique sur “Continue” :

image

 

On nous demande ensuite d’indiquer l’emplacement d’installation des binaires. Je conserve l’emplacement par défaut : C:\Program Files\Microsoft Office Web Apps et on clique sur “Install Now” :

image

 

L’installation débute… on patiente :

image

image

 

L’installation est terminée, on clique sur “Close” :

image

 

En option, vous pouvez également installer les languages packs pour OWA 2013. Pour plus de renseignements, visitez ceci : http://technet.microsoft.com/fr-fr/library/jj219455.aspx => Etape 3.

 

 

3/ Déploiement des Office Web Apps

 

L’étape suivante consiste à créer l’application Web qui permettra d’afficher nos documents. Il existe plusieurs types de configurations suivant votre besoin : http ou https, équilibrage de charge, etc.

Dans mon cas, je reste dans un périmètre interne, tous les utilisateurs se connectent en http. Pour corser un peu le tout, nous allons créer l’application en PowerShell. Pour cela, on reprend notre console PowerShell lancée en administrateur et on exécute :

New-OfficeWebAppsFarm –InternalURL "http://servername" –AllowHttp -EditingEnabled

 

Où :

  • New-OfficeWebAppsFarm : permet de créer la ferme OWA 2013
  • InternalURL : adresse du serveur courant, dans mon cas http://spowa2013
  • AllowHttp : puisque je reste en http
  • EditingEnabled : puisque je veux permettre de lire / modifier les documents

Cela donne :

New-OfficeWebAppsFarm –InternalURL http://spowa2013 –AllowHttp -EditingEnabled

 

Un avertissement vous stipule que pour utiliser le mode édition de document des OWA 2013, il faut que vos utilisateur aient les licences adéquates. Pour savoir si vous pouvez utiliser le mode édition, je vous renvoie vers : http://technet.microsoft.com/fr-fr/library/ff431682.aspx#license.

Pour faire simple, vous avez les licences pour Office 2013, vous pouvez éditer. Sinon la lecture des fichiers est “offerte” par Microsoft.

image

 

Pour configurer les licences à utiliser, reportez vous à : http://technet.microsoft.com/fr-fr/library/jj219627.aspx.

Dans mon cas, je choisis donc “Yes” (Y) :

image

 

La configuration se poursuit. A la fin, un résumé apparait :

image

 

Remarque MSDN : Si des composants de .NET Framework 3.5 ont été installés puis supprimés, il est possible que vous rencontriez des messages de type « Exceptions de service web (500) » ou « Erreur interne du serveur (500.21) » lorsque vous exécutez des applets de commande OfficeWebApps. Pour résoudre ces problèmes, exécutez les exemples de commandes suivants à partir d’une invite de commandes avec élévation de privilèges afin de supprimer les paramètres susceptibles de gêner le fonctionnement normal d’Office Web Apps Server :

%systemroot%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe –iru
iisreset /restart /noforce

 

 

4/ Vérification que tout est ok…

 

Pour cela, nous allons utiliser le service de discovery des Office Web Apps en se connectant tout simplement sur une URL :

http://servername/hosting/discovery

 

Dans mon cas :

http://spowa2013/hosting/discovery

 

Je lance donc simplement un navigateur (IE 10 ici) et on entre l’adresse ci-dessus. Si Office Web Apps Server fonctionne comme prévu, vous verrez s’afficher un flux XML de découverte WOPI (Web app Open Platform Interface). Les premières lignes de ce fichier doivent se présenter comme dans l’exemple suivant : :

image

 

Et ce n’est pas fini…

 

 

5/ Configurer SharePoint Server 2013 pour Office Web Apps 2013

 

Il nous reste maintenant à faire le lien entre notre ferme SharePoint Server 2013 et les Office Web Apps 2013. Et encore une fois… une bonne dose de PowerShell !

Cependant, nous n’allons pas utiliser la console PowerShell 3.0 de Windows Server 2012, mais le SharePoint Management Shell de SharePoint Server 2013… un outil bien connu des administrateurs SharePoint !

Lançons donc la console SharePoint Management Shell, sur le serveur SharePoint bien entendu !

image

 

Puis toujours dans cette console, on lance la commande :

New-SPWOPIBinding -ServerName <WacServerName> -AllowHTTP

 

Dans mon cas (attention aux paramètres suivant ceux fixés lors de la configuration des OWA : http / https en particulier) :

New-SPWOPIBinding –ServerName SPOWA2013 -AllowHTTP

 

image

 

Le Shell vous liste un ensemble de connections WOPI disponibles :

image

 

Puis on exécute :

Get-SPWOPIZone

 

image

Dans les résultats vous devez avoir absolument :

 

Internal-https

 

Et bien sûr nous voudrions avoir du http ! Nous allons donc modifier cette zone avec la commande :

Set-SPWOPIZone –zone “internal-http”

 

Et on relance avec Get-SPWOPIZone pour vérifier que cela a bien été pris en compte :

image

Maintenant nous avons :

 

Internal-http

 

 

Ca sent la fin… mais pas tout de suite. Il nous reste à autoriser l’authentification OAuth sur http pour que cela fonctionne. Pour cela on éxécute :

(Get-SPSecurityTokenServiceConfig).AllowOAuthOverHttp

image

Si cela renvoie “False” dans la console, alors il faut forcer la valeur à “True” :

$config = (Get-SPSecurityTokenServiceConfig)
$config.AllowOAuthOverHttp = $true
$config.Update()

 

On relance une petite vérification :

 

(Get-SPSecurityTokenServiceConfig).AllowOAuthOverHttp

La valeur renvoyée doit être maintenant à “True” :

image

Pour plus d’informations : http://technet.microsoft.com/fr-fr/library/ff431687.aspx.

 

 

6/ Vérification de la configuration globale

 

Pour vérifier… il faut tester ! Nous allons donc nous connecter sur un de nos sites SharePoint avec un compte utilisateur / collaborateur (pas d’administrateur, super admin etc.)

image

 

J’ajoute quelques documents de type Office… dans une bibliothèque de documents :

image

 

On clique sur un des fichiers (PowerPoint pour ma part)… et ça marche !

image

 

Et du Word :

image

 

Et de l’Excel :

image

 

Et un OneNote :

image

 

Notez à chaque fois la présence des boutons dans le ruban pour éditer les documents, les sauvegarder etc. Ca marche plutôt bien !

 

Grâce aux Office Web Apps 2013, nous avons aussi la prévisualisation des documents (dans la bibliothèque de documents et dans la recherche) :

image

 

image

 

Si vous avez activé l’édition / création des documents depuis OWA 2013, lorsque vous cliquez sur le bouton Nouveau document Word, vous pourrez créer vos document directement en Web !

image

image

 

image

 

Voilà, c’est fini !

[SharePoint 2013]–Nouvel outil : SharePoint Color Palette Tool

Posted on Updated on

Avec la sortie de la nouvelle version de SharePoint 2013, nous avons vu (encore) son design général changé. Ce design reprend les principes de Modern UI dictés par Microsoft et repris sur l’intégralité des plateformes : Windows 8, Windows Phone, Xbox.

Nous retrouvons donc dans SharePoint en particulier les Tuiles bien connues, et d’autres un peu moins “Visibles” au premier abord.

SharePoint 2013 apporte également son lot de nouveau thèmes graphiques natifs sur lesquels on peut personnaliser le jeu de couleurs, l’icône, et même la navigation latérale via les materpages oslo.master & seattle.master. Cet éditeur de thèmes permet quand même bien des personnalisations, mais il se peut que cela ne suffise pas !

Dans ces cas là, on peut utiliser le Design Manager permettant d’importer des découpages html pour les convertir en masterpages, les canaux, etc. (voir mon article : SP2013–Design Manager).

 

Pour nous permettre d’aller plus loin, mais sans recourir à SharePoint Designer, aux CSS, aux masterpages, Microsoft nous propose un nouvel outil fraichement releasé : SharePoint Color Palette Tool ! Les prérequis sont Internet Explorer 8 ou supérieur et le Framework 4.5.

Pour ceux qui le connaitraient, pour SharePoint 2010 nous avions Theme Builder renommé Open XML Theme Builder et disponible récemment sur CodePlex : Open XML Theme Builder.

 

Voyons ensemble à quoi cela ressemble !

 

On télécharge l’outil ici : SharePoint Color Palette Tool (1,1Mb).

Et on l’installe (ici sur une machine Windows 8 Enterprise x64 en anglais) :

 

On lance le setup, “Next” :

01

 

On accepte les termes du contrat de licence et “Next” :

02

 

On choisit l’emplacement d’installation, puis “Next” :

03

 

Résumé des information, “Next” :

04

 

L’installation est terminée, on coche “Launch the program”, “Finish” :

05

 

Le programme se lance :

06

 

Premières impressions… plutôt bonnes ! On retrouve sur la gauche un ensemble de contrôles “couleur” avec prévisualisation et code couleur RGB. Au centre, une prévisualisation du résultat (on reprend le thème général de SharePoint 2013) et tout en haut le choix du layout (oslo ou seattle), en dessous un affichage des warnings & erreurs. Sur la droite, un contrôle permet de placer une image en fond, de choisir un jeu de couleurs originel, et au centre un outil permettant de tester le contraste appliqué…

 

Première chose que je vérifie… qu’est-ce que génère cet outil ? En faisant File > Save, on me propose de sauvegarder un fichier *.spcolor :

07

 

Ce fichier spcolor n’est autre qu’un fichier XML :

08

 

Qu’il faudra importer dans SharePoint 2013, pour en savoir plus, direction MSDN : http://msdn.microsoft.com/en-us/library/jj945889.aspx

En fait on retrouve une certaine analogie entre ce fichier spcolor et les css, mais seulement pour la partie couleurs. En effet, on ne retrouve dans ce fichier aucun information sur la masterpage, le layout etc. Donc les paramètres dans l’outil Color Palette ne servent qu’à la prévisualisation, pas au paramétrage du thème en lui-même.

Notons également que dans la zone de gauche, on a des sous items sur lesquels on pourra modifier les couleurs :

09

 

A mon avis, cela va être difficile de faire un jeu de couleur correct dès le premier essai ! Il y a beaucoup de couleurs à paramétrer…

 

Avec 3 ou 4 clics, on arrive à quelque chose… ou pas ! (Notez les warnings…)

10

 

A bientôt !

[Visual Studio & SharePoint]–Paramètres remplaçables

Posted on Updated on

Bonjour à tous.

Si vous développez des projets SharePoint 2010 ou 2013 avec Visual Studio 2010 ou 2012, vous devez connaitre les paramètres remplaçable. En effet, Visual Studio vous permet d’utiliser des sortes de “Pragmas” remplacés à la compilation par Visual Studio lui-même.

Vous reconnaitrez ces paramètres remplaçables rapidement car ils sont entourés par des “$”, du type : $SharePoint.Project.FileName$

Vous retrouverez ces paramètres par exemple dans les pages d’application (Applications Pages), dans l’entête de chacune des pages :

<%@ Assembly Name=”$SharePoint.Project.AssemblyFullName$” %>

Lorsque on lancera la compilation du projet dans Visual Studio, ces paramètres seront remplacés par :

<%@ Assembly Name=”MonProjet.SharePoint, Version=X.X.X.X, Culture=neutral, PublicKeyToken=XXXXXXXXXXXX” %>

Voici le tableau des paramètres remplaçables que vous pourrez utiliser :

Nom du paramètre Description
$SharePoint.Package.Name$ Nom du package
$SharePoint.Package.FileName$ Nom du fichier de définition du package
$SharePoint.Package.FileNameWithoutExtension$ Nom sans extension du fichier de définition du package
$SharePoint.Package.Id$ ID unique SharePoint du package
$SharePoint.Feature.FileName$ Nom du fichier de définition d’une fonctionnalité
$SharePoint.Feature.FileNameWithoutExtension$ Nom du fichier de définition d’une fonctionnalité sans l’extension du nom de fichier
$SharePoint.Feature.Id$ ID unique SharePoint de la fonctionnalité
$SharePoint.Feature.DeploymentPath$ Nom du dossier de la fonctionnalité dans le package
$SharePoint.Project.FileName$ Nom du projet
$SharePoint.Project.FileNameWithoutExtension$ Nom du projet sans l’extension
$SharePoint.Project.AssemblyFullName$ Nom complet de l’assembly du projet
$SharePoint.Project.AssemblyFileName$ Nom de l’assembly du projet
$SharePoint.Project.AssemblyFileNameWithoutExtension$ Nom de l’assembly du projet sans l’extension
$SharePoint.Project.AssemblyPublicKeyToken$ PublicKeyToken de l’assembly
$SharePoint.ProjectItem.Name$ Nom de l’élément de projet
$SharePoint.Type.[GUID].AssemblyQualifiedName$ Nom qualifié de l’assembly
$SharePoint.Type.[GUID].FullName$ Nom complet de l’assembly

Microsoft précise également que l’on peut utiliser ces paramètres remplaçables dans les fichiers de type :

  • XML
  • ASPX
  • ASCX
  • WebPart
  • DWP

Il est possible d’étendre ces possibilités en modifiant le fichier : Microsoft.VisualStudio.SharePoint.targets qui se trouve dans : …\<program files>\MSBuild\Microsoft\VisualStudio\v10.0\SharePointTools

01

On l’édite avec NotePad par exemple :

02

On ajoute des extensions de fichier supportées si besoin. Par contre, si on change de machine, on prendra cette configuration !!! Donc attention, ces paramètres ne seront plus remplacés.

En résumé, ces paramètres sont vraiment très pratiques, et on les utilise très souvent (Visual Studio en utilise lui aussi fréquemment lorsque l’on créé une page d’application par exemple).

Pensez-y !

SP2010-Remplacer les formulaires – Part 1 – Template de Liste

Posted on Updated on

Bonjour à tous.

Cela fait maintenant quelques semaines que je n’ai pas bloggé, je profite d’une petite “accalmie” pour publier un article qui vous montrera comment déployer des formulaires NewForm.aspx; EditForm.aspx et DispForm.aspx dans SharePoint 2010 (fonctionnera également avec SharePoint 2007 & 2013).

Bien souvent, quand je me déplace chez des clients ou que je reprend des développements qui ont été réalisés, je m’aperçois que ces formulaires ont été ré-implémentés et redéployés par le biais d’une solution SharePoint, ce qui est plutôt bien. Ce qui me choque en général, c’est que ces formulaires ne viennent pas remplacer “physiquement” les existants mais s’ajoutent aux formulaires existants, avec des nouveaux noms : newform2.aspx, editform2.aspx ou encore dispform2.aspx.

Si des utilisateurs (malins) connaissent les url vers les formulaires natifs, ils pourront toujours les utiliser !!! Et ça, c’est vraiment pas bien !

Je vais donc tenter de vous expliquer comment remplacer ces formulaires (les écraser en fait) par le biais d’une solutions SharePoint… et sans utiliser du C# => Chalenge Sourire

Nous essaierons d’utiliser au maximum les API natives de SharePoint et les fichiers XML de déploiements supportés.

Dans un second temps, j’aimerai également vous montrer comment remplacer/overrider le comportement natifs des contrôles dans ces formulaires… mais ça sera pour un prochain article !

Première chose, se connecter sur une collection de sites, un site et créer une liste. Dans mon cas ce sera une liste custom… et même une seconde liste que je créée par avance pour la suite de l’article. Je vais également créer une colonne de type lookup (recherche d’éléments déjà présents sur le site) qui “reliera” mes deux listes… Et encore une troisième qui utilisera elle aussi une colonne de type lookup :

On aura donc trois listes avec leurs attributs :

image

  • Pays contiendra le nom du pays, sa surface et son nombre d’habitants
  • Ville contiendra le nom de la ville, le pays d’appartenance, sa surface et son nombre d’habitants
  • Commande contiendra le titre de la commande, le montant, le pays et la ville. Dans un premier temps on utilisera deux lookup, pointant sur chacune de listes pays & ville. On remplacera plus tard ce comportement par des listes déroulantes liées et pré-filtrées. On sélectionnera le pays et cela filtrera la liste des villes proposées. Mais tout cela dans un second temps.

1/ Commençons par créer une solution avec Visual Studio 2010

NB : il faudra travailler un maximum en utilisant les noms internes des objets (List, Site, Web, Field) afin d’éviter les problème de renommage de ces objets (display name). On utilisera donc au maximum les staticName, internalName ou encore Name lorsqu’il seront disponibles sur ces éléments.

Commençons donc par la création de notre solution SharePoint dans Visual Studio 2010 que j’appelle DEMO1, de type “Empty SharePoint Project” :

image

On renseigne l’url du site de déploiement (debug) et on choisit une solution de type “Farm” :

image

La solution est créée, elle est vide ou presque :

image

Nous allons ensuite faire un clic droit sur le projet et ajouter un nouvel élément (Add New Item), de type SharePoint > 2010 > List Definition et on la nomme “Pays”. Cliquer sur “Add” :

image

Un assistant se lance pour nous aider à créer la structure générale de ce nouvel élément. Ainsi, on renseigne le nom d’affichage de notre modèle de liste. “Pays” dans mon cas, et on choisit le modèle “Custom List” qui est basique et conviendra très bien à notre exemple. Je choisis également de créer une instance lorsque la “Feature” déployant notre solution sera activée. On clique sur “Finish” :

image

La structure générale de la liste est créée :

image

On observe tout de suite que Visual Studio n’a pas créé 1 seul fichier mais bien un ensemble. Dans le “Répertoire” Pays, on retrouve 2 fichiers XML :

  1. Elements.xml : décrit à SharePoint comment déployer le modèle lors de l’ajout de ce modèle
  2. Schema.xml : décrit la structure des éléments à déployer : colonnes, vues, etc.

Dans le sous dossier ListInstance1, on retrouve également un fichier XML “Elements.xml” qui décrira comment créer une instance de cette liste à partir du modèle lors de l’activation de la Feature : nom de la liste, url, visibilité, etc.

Nous allons ensuite reproduire 2 fois ces manipulations pour créer deux nouvelles listes : Ville et Commandes :

image

J’ai pris le soin ici de renommer correctement les instances dans l’explorateur de solutions.

2/ Modifier les modèles de liste – Elements.xml

Notre structure générale est créée. Passons maintenant à l’enrichissement de ces modèles en les personnalisant, en ajoutant de nouvelle colonnes, etc.

Pays

Pour la liste pays, nous devons :

  • Ajouter les colonnes Surface, NbrHabitants
  • Masquer le modèle dans la galerie (les utilisateurs/power users ne pourront pas créer de nouvelles instances à partir de ce modèle)
  • personnaliser par-ci, par-là Sourire

Commençons par le fichier Elements.xml du modèle de liste :

<ListTemplate
Name=”Pays”
Type=”10000″
BaseType=”0″
OnQuickLaunch=”TRUE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Pays”
Description=”My List Definition”
Image=”/_layouts/images/itgen.png”/>

Nous allons commencer par modifier les attributs existants :

  • Name=”Pays” => cela me convient
  • Type=”10000” (attention il ne faudra pas avoir un autre modèle sur la plateforme portant ce numéro)
  • BaseType=”0” => cela me convient (on aura 1 pour les bibliothèques de documents)
  • OnQuickLaunch=”TRUE” => Je change en FALSE, la liste n’apparaitra pas pas défaut dans la barre de navigation rapide “QuickLaunch”
  • SecurityBits=”11″ => OK
  • Sequence => aucune importance, le modèle sera masque dans la galerie des modèles de liste (ordre de tri dans cette galerie)
  • DisplayName=”Pays” => OK
  • Description=”My List Definition” => On donne une description
  • Image=”/_layouts/images/itgen.png”/ => Je vais changer pour fournir une image un peu plus sympa, que je déploierais grâce à la solution dans 14/TEMPLATES/IMAGES/DEMO/monimage.png

On ajoutera les attributs :

  • Category=”Custom Lists” => pas obligatoire
  • DisableAttachments=”TRUE” => on désactive les pièces jointes
  • FolderCreation=”FALSE” => on désactive la création de répertoires
  • Hidden=”TRUE” => On masque le modèle dans la galerie
  • VersioningEnabled=”FALSE” => on désactive le versioning

Ce qui donne :

ListTemplate
Name=”Pays”
Type=”10000″
Category=”Custom Lists”
DisableAttachments=”TRUE”
FolderCreation=”FALSE”
Hidden=”TRUE”
VersioningEnabled=”FALSE”
BaseType=”0″
OnQuickLaunch=”FALSE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Pays”
Description=”Modèle de liste pays”
Image=”/_layouts/images/demo/pays.png”/>

Notez également qu’il vous sera possible de “localiser” les noms (Name, Description par exemple) pour faire la traduction automatique suivant la langue du navigateur/UI.

Ville

Nous allons effectuer les mêmes manipulation sur le fichier Elements.xml du modèle de liste Ville :

<ListTemplate
Name=”Ville”
Type=”10001″
Category=”Custom Lists”
DisableAttachments=”TRUE”
FolderCreation=”FALSE”
Hidden=”TRUE”
VersioningEnabled=”FALSE”
BaseType=”0″
OnQuickLaunch=”FALSE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Ville”
Description=”Modèle de liste ville.”
Image=”/_layouts/images/demo/villes.png”/>

Commandes

Pour la liste commande, on reproduit les mêmes manipulations, sauf que ne masquera pas ce modèle pour pouvoir créer de multiples instances de cette liste. Nous modifierons également l’attribut OnQuickLaunch à TRUE :

<ListTemplate
Name=”Commandes”
Type=”10002″
Category=”Custom Lists”
DisableAttachments=”TRUE”
FolderCreation=”FALSE”
VersioningEnabled=”FALSE”
BaseType=”0″
OnQuickLaunch=”TRUE”
SecurityBits=”11″
Sequence=”410″
DisplayName=”Commandes”
Description=”Modèle de liste commandes.”
Image=”/_layouts/images/demo/commandes.png”/>

3/ Modifier les modèles de liste – Schema.xml

Maintenant, il nous faut modifier les 3 fichiers Schema.xml pour ajouter les nouvelles colonnes sur chacun de nos 3 modèles.

Pays

Dans notre liste pays, nous allons ajouter deux colonnes supplémentaires : Surface & NbrHabitants. Pour cela, on ouvre le fichier Schema.xml du modèle de liste Pays :

image

Dans cette structure XML, on distinguera 4 parties principales :

  • ContentTypes : déclaration des types de contenus associés à la liste, ici celui élément (Item)
  • Fields : métadonnées/colonnes/champs associés à ce modèle de liste
  • Views : Vues disponibles sur ce modèle de liste
  • Forms : formulaires d’ajout/modification/affichage de chaque élément de cette liste

Nous allons modifier principalement les <Fields /> pour ajouter les deux colonnes. Ici plusieurs écoles s’affrontent. Vous pouvez partir de rien, aidé par l’IntelliSense de Visual Studio ou alors créer une liste et ces colonnes dans SharePoint et utiliser SharePoint Manager 2010 pour récupérer le schéma généré par SharePoint. Pour sa facilité, je choisirai la seconde option, mais en restant vigilant sur le flot de XML généré…

J’ai donc créé une liste “pays” dans SharePoint et créé les colonnes demandées.

On prendra soin également de choisir le type de champ le plus pertinent pour nos données : texte, monnaie, nombre, recherche, etc.

image

    Voila donc le formulaire d’ajout d’un pays :

image

Vous trouverez de quoi télécharger SharePoint Manager 2010 sur CodePlex : SharePoint Manager 2010.

On lance SharePoint Manager 2010, et on explore l’arborescence de nos sites jusqu’à arriver sur notre liste “Pays” :

image

Dans la section de droite, vous trouverez un onglet “SchemaXml” avec l’ensemble du schéma :

image

On repère rapidement, dans la section <Fields> que nos deux champs créés précédemment apparaissent :

  • <Field Type=”Number” DisplayName=”Surface” Required=”FALSE”… />
  • <Field Type=”Number” DisplayName=”NbrHabitants” Required=”FALSE” … />
    Ce sont ces deux nœuds XML qu’il va falloir intégrer au fichier Schema.xml. On copie donc ces deux lignes et on les colle dans Schema.xml, dans le nœud <Fields></Fields> :

image

Petite option supplémentaire, on peut directement ajouter ces deux champs dans les différentes vues proposées par notre modèle de liste Pays. Pour cela, dans Schema.xml, on ouvre le nœud <Views>, on y trouve deux nœuds <View></View>. Une des vues sera utilisée pour les terminaux de type mobiles, et l’autre pour l’affichage par défaut dans le navigateur de cette liste “Pays”. Nous allons directement modifier la vue commençant par :

<View BaseViewID=”1″ Type=”HTML” WebPartZoneID=”Main”

Et ajouter dans le sous-noeud <ViewFields> deux nouvelles lignes (en copiant/collant 1 existante) et en modifiant l’attribut Name avec les noms de noms champs. Je supprime également le Field Attachments correspondant aux pièces jointes que j’ai désactivé dans la déclaration du Template (voir Elements.xml précédent) :

        <ViewFields>
<FieldRef Name=”LinkTitle”></FieldRef>
<FieldRef Name=”Surface”></FieldRef>
<FieldRef Name=”NbrHabitants”></FieldRef>
</ViewFields>

Attention, l’ordre a son important, les premières lignes deviendront les premières colonnes dans l’affichage. On obtiendra donc :

image

Notez également le nœud <OrderBy> au dessous qui vous permettra d’ordonner votre liste sur les noms des pays, alphabétiquement. Je modifie donc :

        <Query>
<OrderBy>
<FieldRef Name=”Title”></FieldRef>
</OrderBy>
</Query>

C’est tout pour ce modèle de liste. Passons maintenant à l’instance qui sera créé à partir de ce modèle. Pour cela, on se rend dans l’explorateur de solution et on ouvre le fichier Elements.xml de l’instance de la liste Pays :

image

Dans ce dernier, nous allons encore modifier la structure XML pour paramétrer l’instance de la liste Pays qui sera automatiquement créée lors de l’activation de la feature (nous y reviendrons…).

On modifie pour obtenir :

<ListInstance Title=”Pays”
OnQuickLaunch=”FALSE”
TemplateType=”10000″
Url=”Lists/Pays”
Description=”Liste des pays”>
</ListInstance>

Notez que le TemplateType est le même que celui définit dans le <ListTemplate>, c’est très important ! Sinon SharePoint ne saura pas quel modèle utiliser pour créer l’instance. Pour l’url, ma liste sera accessible à l’adresse :

Ville

Nous allons reprendre les mêmes manipulations pour ce modèle de liste. Nous allons utiliser également SharePoint Manager 2010 pour récupérer les nœuds XML des colonnes.

Nous utilisons SharePoint Manager 2010, récupération des nœuds XML, copier/coller, etc.

image

Dans le Schema.xml, nous  ajoutons donc :

<Fields>
<Field Type=”Number” DisplayName=”Surface” Required=”FALSE”…

<Field Type=”Number” DisplayName=”NbrHabitants” Required=”FALSE”…

<Field Type=”Lookup” DisplayName=”Pays” Required=”TRUE”…

</Fields>

Jusqu’ici, nous n’avions eu que des colonnes texte ou nombre. Nous venons d’ajouter un nouveau type de colonne, le type “Lookup” (Recherche d’information déjà présentes sur le site). Ces champs permettent de référencer des données qui sont stockées dans une autre liste/bibliothèque SharePoint. Si l’on regarde les différents attributs proposés, on note :

  • List=”{1f675688-39f5-441d-bdb7-19f7c3dce646}”
  • ShowField=”Title”
    Ce sont ces deux attributs qui établissent la relation entre la liste Ville et la liste Pays et plus particulièrement la colonne “Title” de la liste Pays. Lorsque nous déploierons cette solution/feature, SharePoint ne saura pas faire le lien entre ces deux listes, parce que, tout simple le GUID de la liste Pays va être régénéré !!! Et oui… il va donc falloir remplacer ce premier attribut “List” par autre chose (et si possible pas de code C# qui recréera cette relation).
    Après un petit tour dans le SDK de SharePoint, on s’aperçoit qu’il est possible de remplacer ce GUID par l’adresse relative de cette liste : Lists/Pays. On obtient donc :

<Field Type=”Lookup” DisplayName=”Pays” Required=”TRUE” EnforceUniqueValues=”FALSE” List=”Lists/Pays” ShowField=”Title”

Pour la vue par défaut de cette liste, nous effectuons également les modification afin que ces champs apparaissent dans la vue :

image

C’est tout pour ce modèle de liste. Passons maintenant à l’instance qui sera créé à partir de ce modèle. Pour cela, on se rend dans l’explorateur de solution et on ouvre le fichier Elements.xml de l’instance de la liste Ville :

image

Dans ce dernier, nous allons encore modifier la structure XML pour paramétrer l’instance de la liste Ville qui sera automatiquement créée lors de l’activation de la feature (nous y reviendrons…).

On modifie pour obtenir :

<ListInstance Title=”Villes”
OnQuickLaunch=”FALSE”
TemplateType=”10001″
Url=”Lists/Villes”
Description=”Liste des villes.”>
</ListInstance>

image

Notez que le TemplateType est le même que celui définit dans le <ListTemplate>, c’est très important ! Sinon SharePoint ne saura pas quel modèle utiliser pour créer l’instance. Pour l’url, ma liste sera accessible à l’adresse :

Commandes

Pour cette dernière liste, nous allons reproduire exactement les mêmes étapes mais cette fois-ci, nous aurons deux champs de type “lookup”.

Dans le schema.xml nous aurons donc :

<Fields>
<Field Type=”Currency” DisplayName=”Montant” Required=”TRUE” … />
<Field Type=”Lookup” DisplayName=”Pays” Required=”TRUE” …  List=”Lists/Pays” ShowField=”Title” … />
<Field Type=”Lookup” DisplayName=”Ville” Required=”TRUE” List=”Lists/Villes” ShowField=”Title” … />

</Fields>

image

C’est tout pour ce modèle de liste. Passons maintenant à l’instance qui sera créé à partir de ce modèle. Pour cela, on se rend dans l’explorateur de solution et on ouvre le fichier Elements.xml de l’instance de la liste Commandes :

image

Dans ce dernier, nous allons encore modifier la structure XML pour paramétrer l’instance de la liste Commandes qui sera automatiquement créée lors de l’activation de la feature (nous y reviendrons…).

On modifie pour obtenir :

<ListInstance Title=”Commandes”
OnQuickLaunch=”TRUE”
TemplateType=”10002″
Url=”Lists/Commandes”
Description=”Liste de commandes.”>
</ListInstance>

image

Notez que le TemplateType est le même que celui définit dans le <ListTemplate>, c’est très important ! Sinon SharePoint ne saura pas quel modèle utiliser pour créer l’instance. Pour l’url, ma liste sera accessible à l’adresse :

Certains diront qu’il y a des attributs qui ne seront pas utilisé dans notre structure XML (Schema.xml, Elements.xml), je vous laisse vous reporter au SDK, Technet et autre pour faire le tri….

4/ Créer le package de déploiement

Il nous reste une étape, et pas des moindres, créer la solution, la feature qui permettra de déployer nos modèles de listes. Pour cela, Visual Studio nous aide bien (et c’est tout à son honneur quand on a connu SharePoint 2003 & 2007…).

Nous allons donc nous rendre dans le répertoire Features où nous remarquons qu’une feature est déjà disponible :

image

On double-clique, l’assistant de configuration des features apparait :

image

Aucun des modèles/instances n’est ajouté à la feature. Commençons par cela, on utilise les “flèches du milieu” pour faire passer les éléments de gauche à droite :

image

Nous allons également renommer la feature, donner une petite description, etc. Il vous sera également possible d’ajouter une petite icone pour distinguer plus rapidement vos features.

Chose importante, je souhaiterai que mes listes Pays & Villes ne soient créées (leurs instances plus particulièrement) que sur le site à la racine de la collection (RootWeb). Pour cela, le plus simple et de changer le Scope (Etendue) en Site (Collection de sites).

image

Et c’est tout… Bien sûr suivant le projet et les éléments qui le composent, vous choisirez peut être d’utiliser plusieurs fonctionnalités, avec des scopes différents…

5/ Le test !

C’est parti pour le test… vous pouvez utiliser F5 (mode debug… qui ne débuggera rien ici !) ou alors le clic droit sur le projet, Build, Deploy. Ce choisis la seconde option.

Vous aurez peut être une erreur lors du déploiement vous disant que Pays et Pays se déploie dans le même emplacement. En effet en regardant les chemins (path) de déploiement on s’aperçoit que les instances se déploient dans le même répertoire que la définition. Je renomme dans les modèles de liste :

image

Vous obtiendrez peut être cette fenêtre de warning :

image

Elle vous informe tout simplement qu’une liste avec le même nom “Pays” existe deja. On coche “Do not prompt me again for these items” puis on clique sur “Resolve automatically”…

Déploiement réussi :

image

Il faudra également ajouter les images correspondant aux miniatures de nos listes. J’ai fait quelques petits changements dans les Elements.xml des modèles en modifiant l’attribut Image :

  • Image=”/_layouts/images/demo/pays16x16.png”/
  • Image=”/_layouts/images/demo/villes16x16.png”/
  • Image=”/_layouts/images/demo/commandes16x16.png”/

Voila ce que cela donne dans le menu “View all site content” :

image

Rendons nous sur chacune des liste afin de vérifier :

  • La déclaration des vues/affichages (colonnes présentes, tris)
  • La déclaration des colonnes créées

Coté affichage, rien à signaler. Par contre si on lance le formulaire d’ajout d’un pays/ville/commandes, le formulaire ne présente que le champ Titre !!! Effectivement, c’est un comportement particulier de SharePoint voire étrange que l’on constate ici.

Premier réflexe, ajouter les attributs :

ShowInNewForm=”TRUE” ShowInEditForm=”TRUE” ShowInDisplayForm=”TRUE”

Sur chacun des champs. Mais cela n’aura aucun effet. Nous aurons alors deux choix :

  • Recourir à un type de contenu SharePoint
  • Supprimer les types de contenu

En général, je me tourne vers la première option. Mais dans notre cas, aucun intérêt de créer des types de contenu (ContentTypes) vu qu’on ne les utilisera qu’une seule fois (pour Pays & Ville) et qu’on ne réutilisera pas non plus la structure de Commandes (si ce n’est pour créer de nouvelles listes de commandes => et pas des sous-enfants).

Voila donc comment faire fonctionner tout cela. Première opération, supprimer les sections <ContentTypes>…</ContentTypes> ou tout du moins le contenu => <ContentTypes/> dans les 3 Schema.xml :

image

On sauvegarde le tout et on redéploie… et là, magique :

image

5/ Charger des données

Une petite dernière chose, avant de passer à la suite… Les listes étant créées, elles seront supprimées, recréées à chaque déploiement depuis Visual Studio. Pour ne pas perdre trop de temps à se recréer un jeu de test, nous pouvons remplir ces listes directement depuis leur définition. C’est ce qu’on appelle les RowData.

Nous allons commencer par ajouter des données dans Pays puis Ville. Cette méthode est aussi très pratique pour remplir automatiquement des listes de paramètres stockées dans SharePoint (ici notre liste de Pays ne change pas tous les jours…). Voila comment faire.

Dans chacun des fichiers Elements.xml des instances de nos listes, nous allons ajouter un bloc de XML :

<ListInstance Title=”Pays”
OnQuickLaunch=”FALSE”
TemplateType=”10000″
Url=”Lists/Pays”
Description=”Liste des pays”>
<Data>
<Rows>
<Row>
<Field Name=””></Field>
</Row>
</Rows>
</Data>
</ListInstance>

En résumé, les nœuds XML :

  • Data : ensemble des données à ajouter
  • Rows : collection des lignes (ensemble d’enregistrements)
  • Row : 1 ligne d’enregistrement
  • Field : champ à valoriser pour l’enregistrement courant.

Donc pour un pays, on aurait (données recueillies sur www.france.fr) :

    <Data>
<Rows>
<Row>
<Field Name=”Title”>France</Field>
<Field Name=”Surface”>543965</Field>
<Field Name=”NbrHabitants”>65350000</Field>
</Row>
</Rows>
</Data>

En on recréée une structure Row pour chacun des pays. J’en ajouterai une petite dizaine pour les tests.

image

On remarque tout de suite que les pays sont triés sur le nom (alphabétique) alors dans le Schema.xml :

        <Row>
<Field Name=”Title”>France</Field>
<Field Name=”Surface”>543965</Field>
<Field Name=”NbrHabitants”>65350000</Field>
</Row>
<Row>
<Field Name=”Title”>Espagne</Field>
<Field Name=”Surface”>505911</Field>
<Field Name=”NbrHabitants”>46754784</Field>
</Row>
<Row>
<Field Name=”Title”>Angleterre</Field>
<Field Name=”Surface”>130395</Field>
<Field Name=”NbrHabitants”>52234000</Field>
</Row>

Nous allons faire la même chose avec les Villes. Petite différence, le champ lookup qui pointe sur la liste des Pays… Et c’est donc un peu différent. En effet, les champs lookups doivent être renseigné avec ID;#Valeur :

         <Row>
<Field Name=”Title”>Marseille</Field>
<Field Name=”Surface”>240</Field>
<Field Name=”NbrHabitants”>850602</Field>
<Field Name=”Pays”>1;#France</Field>
</Row>
<Row>
<Field Name=”Title”>Madrid</Field>
<Field Name=”Surface”>608</Field>
<Field Name=”NbrHabitants”>3413271</Field>
<Field Name=”Pays”>2;#Espagne</Field>
</Row>

Attention, l’ID et celui dans SharePoint (et donc dans l’ordre d’insertion qui correspond à l’ordre dans l’Element.xml de la liste Pays !)

image

Et voilà ! Puisque les listes sont supprimées à chaque déploiement, nous n’auront pas besoin de remplacer les ID dans les fichiers Elements.xml.

Dernière vérification, la liste de commandes est-elle bien renseignée ?? Bien sûr que oui !

image

Par contre on voit tout de suite que Barcelone n’est pas en Allemagne… Clignement d'œil

Et donc… prochain article… ré-implémenter le comportement de ce formulaire… et faire communiquer nos deux liste déroulantes !

SharePoint 2010 & Visual Studio 2012–Step 5–Nouveautés & Ma première application Silverlight avec OData

Posted on Updated on

Bonjour à tous.

Encore un nouveau billet concernant les nouveautés de Visual Studio 2012 RC pour le développement SharePoint 2010. Petit rappel :

Nous allons rentrer plus en détail dans le développement avec la création d’un WebPart Silverlight permettant de requêter des données par le biais de OData.

Mais me direz-vous, qu’est-ce que OData ? Je vous conseille pour cela un peu de lecture glanée sur le Web :

Pour résumer, c’est la possibilité d’interroger des données au travers d’un WebService (http/https) via un protocole défini et standardisé retournant du JSON ou ATOM (du XML de reste). Je vous laisse vous documenter sur ce sujet.

Revenons à notre thèmes principal. Comment créer ce WebPart Silverlight, le packager et le déployer dans SharePoint 2010 en utilisant Visual Studio 2012. C’est ce que nous allons voir !

(Je précise que Silverlight n’est pas ma tasse de thé !)

1/ Créer le WebPart dans la solution.

Je vous rappelle que nous avions laissé la solution dans cet état au précédent billet :

100

Nous avons déjà créé une colonne de site, un content type et un modèle de bibliothèque de documents.

Pour créer notre WebPart Silverlight, commençons par faire un clic-droit sur le projet, puis “Add > New Item”

101

Dans la fenêtre qui s’ouvre, sélectionner “Silverlight WebPart” et nommons le “WPSilverlight” puis cliquer sur “Add” :

102

Une nouvelle fenêtre s’ouvre, sélectionner “Create a new…” si ce n’est pas déjà fait. Cela va créer un nouveau projet dans la solution actuelle, de type Silverlight qui abritera tout le projet permettant d’implémenter le contrôle Silverlight. Le projet sera compilé puis les binaires seront copiés dans la solution SharePoint automatiquement. Pratique !

On paramètre donc le nom du projet, le répertoire de création du projet, le langage (C#) puis la version de Silverlight (5.0 dans mon cas, 4.0 est aussi disponible). Puis cliquer sur “Finish” :

103

Après quelques secondes, le nouveau projet est créé et le designer Silverlight se charge :

104

106

Dans le projet SharePoint, une nouvelle fonctionnalité (feature) est créée et référencera tous les fichiers utiles pour notre projet Silverlight en particulier les fichiers XML permettant de référencer notre WebPart dans SharePoint. On retrouve donc le fichier “Elements.xml” et “WPSilverlight.webpart” dans cette feature :

107

Le fichier “Elements.xml” va permettre de déclarer le que SharePoint doit utiliser le fichier “WPSilverlight.webpart” mais également le fichier XAP produit par le projet Silverlight :

108

Et dans le fichier “WPSilverlight.webpart” on déclare à SharePoint comment déployer notre WebPart contenu dans la solution. On va par exemple indiquer dans quelle catégorie placer le WebPart, ses dimensions par défaut, son nom dans la galerie de WebParts ou encore un éventuel message d’erreur qui pourra apparaitre lorsque l’utilisateur ne parviendra pas à ajouter ce composant sur une page :

109

2/ Voyons maintenant ce fameux projet Silverlight :

112

Un bon nombre de références sont déjà ajoutées au projet, essentielles aux WebParts Silverlight pour SharePoint 2010.

Cependant un certain nombre de références vont nous être utilises afin de requêter en OData des données provenant de SharePoint. Nous allons donc ajouter deux références au projet Silverlight :

  • System.Windows.Data
  • System.Data.Services.Client

Pour cela, clic-droit sur le répertoire “References” dans le projet Silverlight puis “Add Reference” :

113

Nous allons rechercher nos deux références dans les Assemblies déjà disponibles sur le serveur :

114

115

116

117

118

3/ Notre projet référence maintenant les bonnes Assemblies. Il va falloir ajouter une référence vers le WebService SharePoint 2010 afin de requêter ces données (créer la DataSource).

Pour cela, nous allons ajouter un “Service Reference”. Clic-droit sur le projet, “Add Service Reference” :

119

Une fenêtre s’ouvre où nous allons saisir l’URL du WebService en question… nous ne la connaissons pas encore, mais cela reste simple ! Pour cela, nous allons juste entrer l’URL de notre site SharePoint. Dans mon cas http://sp2010demo  et on clique sur “Go”. Visual Studio 2012 va rechercher tout seul le service qui doit être exposé par SharePoint :

120

Une fois trouvé, Visual Studio va rajouter seul le bout d’URL manquant, vous n’avez rien à faire. Il va donc rajouter : /_vti_bin/ListData.svc et présenter le service (Panel de gauche) disponible. Il vous suffit de nommer votre nouveau service (“ServiceReference”) et cliquer sur “OK”.

121

La référence au service est bien ajoutée au projet Silverlight dans la solution :

122

4/ Nous allons essayer de compiler la solution afin de vérifier qu’il n’y a aucun problème. Dans mon cas j’ai quelques centaines d’erreurs qui remontent (337 pour être exact) !

123

Rien de grave, en fait en ajoutant nos références aux Assemblies, le compilateur s’y perd un peu mais rien de dramatique. Afin de supprimer ces erreurs, il vous suffira de supprimer deux références qui ont été ajoutées à la création du projet :

  • Microsoft.Data.OData.SL
  • Microsoft.Data.Services.Client.SL

On sélectionne donc ces deux références et on les supprime :

124

125

126

On compile, pas d’erreur… c’est la fête :

127

5/ La référence au service de requêtage des données est ajoutée, nous allons maintenant créer la fameuse DataSource qui nous permettra de “binder” les données provenant de SharePoint à un contrôle Silverlight de manière automatique. Pour cela, on sélectionne la référence au service puis on se dirige sur le menu “DATA” puis “Show Data Sources” :

128

Sur la gauche, une boite à outils s’ouvre présentant la DataSource récupérer par la référence au WebService SharePoint et on voit immédiatement les listes et bibliothèques SharePoint de notre site apparaitre :

129

Et là… rien de plus simple ! Ouvrons notre fichier MainPage.xaml contenant la fenêtre principale de notre application Silverlight…

130

On choisit une liste dans la DataSource (dans mon cas “Premiereliste” qui est l’instance de liste créée lors du déploiement de ma solution SharePoint, à partir du modèle) :

131

Un coup de Drag&Drop (glisser-déposer… Clignement d'œil) et c’est gagné !

132

Immédiatement, Visual Studio ajoute une DataGrid “bindée” sur notre DataSource dans la fenêtre du designer Silverlight.

il nous reste à fixer les dimensions, aligner, … faire du beau quoi !

133

Oh que c’est beau…

6/ Et ce n’est pas encore fini, maintenant il nous reste à mettre en place le mécanisme de chargement Asynchrone de notre DataGrid. Pour cela, nous allons faire un tout petit peu de code.

Ouvrons donc le fichier C# associé à notre MainPage.xaml (F7 depuis le designer Silverlight).

134

Première chose, ajouter les “usings” adéquats :

  • using SilverlightProject.ServiceReference //(référence vers le service créé tout à l’heure)
  • using System.Windows.Data
  • using System.Data.Services.Client

135

On enregistre, compile. Tout est ok.

Ensuite nous allons créer 3 attributs à la classe :

  • private IntranetDataContext context;
  • private CollectionViewSource collviewsource;
  • DataServiceCollection<PremiereListeItem> premierelistitems = new DataServiceCollection<PremiereListeItem>();

136

Et enfin implémenter deux méthodes, celle proposée par Visual Studio (UserControl_Loaded) puis dans un seconde temps une deuxième (premierelistitems_LoadCompleted).

La première sera appelée lorsque le UserControl Silverlight aura été chargé (à la fin du chargement du contrôle) et la seconde à la fin du chargement des données depuis la DataSource et qui bindera les données avec le contrôle.

Je ne détaille pas le code, ce n’est pas vraiment pertinent pour l’exemple.

137

private void UserControl_Loaded_1(object sender, RoutedEventArgs e)
{
    context = new IntranetDataContext(new Uri("http://sp2010demo/_vti_bin/ListData.svc"));
    if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
    {
       collviewsource = (System.Windows.Data.CollectionViewSource)this.Resources["premiereListeViewSource"];
       premierelistitems.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(premierelistitems_LoadCompleted);
       premierelistitems.LoadAsync(context.PremiereListe);
    }           
}
private void premierelistitems_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
    if (e.Error == null)
    {
       collviewsource.Source = premierelistitems;
    }
    else
    {
       MessageBox.Show(string.Format("Une erreur s'est produite : {0}", e.Error.Message));
    }
}

Bien sûr il faut compiler. Tout doit être Ok. Il nous maintenant à déployer sur notre site SharePoint 2010. Mais avant cela nous allons vérifier que le debug pour les application Silverlight est bien activé. Pour cela, il faut se positionner sur le projet SharePoint, clic-droit, “Properties” :

138

Dans la partie SharePoint, il faut vérifier que la checkbox “Enable Silverlight debugging…” soit bien cochée. On sauve, compile.

139

Puis on déploie comme vu dans les précédents billets (F5 pour debugger) :

140

6/ Le navigateur s’ouvre sur l’accueil de notre site SharePoint. Il nous faut éditer la page d’accueil pour ajouter le composant WebPart :

144

Dans le ruban, Insérer > Composant WebPart :

145

Dans la galerie de WebParts, le notre apparait bien dans la section “Custom” => SharePointProject1 – WPSilverlight. On cliquer sur “Ajouter” :

146

Le WebPart est ajouté :

147

On sauvegarde la page :

148

7/ Aucune donnée n’apparait. Normal, la liste est vide ! Ajoutons donc un petit document de test :

149

150

151

152

Revenons sur la page d’accueil :

153

Le document que nous venons d’ajouter apparait bien. Vous pouvez directement debugger votre projet Silverlight depuis Visual Studio 2012 au besoin.

Plutôt simple non ? qu’est-ce qu’à ajouté Visual Studio 2012 sur ce mini-développement ? Principalement de nouvelles interface qui ont été intégrées au niveau des DataSources. On peut maintenant requêter très facilement des données SharePoint au travers des services OData et utiliser la source de données produite dans plusieurs type de projet. Cela ne se limite pas au Silverlight. En effet, on pourrait très bien créer une application cliente Métro/WPF qui présenterait ces données de la même manière. Un bon point pour VS2012 !