Archives de mot-clé : REST

Créer un add-in part SharePoint Hosted pour afficher vos nouvelles avec le nombre de commentaires et de mentions « J’aime »

Je viens tout juste de publier mon premier vidéo sur le site Channel 9 :

video

Code source :

Pour s’y faire les technologies suivantes seront utilisées :

  • JavaScript
  • jQuery
  • SharePoint Hosted Add-in Part
  • SharePoint REST API

Je vous inviter à commenter et à évaluer ce vidéo !

 

Publicités

Conférence sur le développement d’applications basées sur la recherche (API REST) @ SharePoint Saturday Montréal

Introduction

Le 23 mai 2015 avait lieu au Collège Maisoneuve, 2701 Rue Nicolet, Montréal l’événement SharePoint Saturday Montréal. J’ai eu la chance de participer à cet événement en tant que conférencier.

SharePointSaturday

Ma session

Titre : Développement d’applications basées sur la recherche (API REST)

Track: Développeur
Description : Dans SharePoint, il n’existe pas nativement de fonctionnalité pour obtenir des résultats de recherche asynchrone.
Pourtant, cela semble être très populaire chez plusieurs clients qui veulent offrir une expérience utilisateur similaire à Google.
Il existe plusieurs librairies tierces gratuites permettant d’effectuer le travail. Celles-ci s’intègrent dans SharePoint très facilement en interrogeant l’API REST de recherche natif.
Nous présenterons le code et une démonstration qui illustrera comment il est possible de développer des applications basées sur la recherche autant dans O365 que On-Premise.
Les sources  :
telecharger-bouton
La présentation :
telecharger-bouton

Les autres sessions

Plusieurs autres conférenciers on présentés des sessions de qualité et si vous ne pouviez pas y assister, la majorité de leur présentation est disponible sur le site du SharePoint Saturday Montreal !
J’ai bien apprécié la session de mon collègue Gilberto Rancourt sur « SharePoint pour le déploiement de votre intranet d’entreprise » avec sa fameuse pyramide.

Conclusion

Un super événement GRATUIT, du smoked meat et d’excellents conférenciers.

Utiliser jQuery UI autocomplete et l’API REST de SharePoint pour obtenir des résultats de recherche de personne

Introduction

Le complètement automatique, ou encore par anglicisme l’autocomplétion, est une fonctionnalité informatique permettant à l’utilisateur de limiter la quantité d’informations qu’il saisit, en se voyant proposer un complément qui pourrait convenir à la chaîne de caractères qu’il a commencé à taper. Dans SharePoint, ce type de fonctionnalité n’existe pas nativement pour obtenir des résultats de recherche de personnes et pourtant ça semble être très en demande par plusieurs clients qui veulent offrir une expérience utilisateur similaire à Google.

Prérequis

  • Avoir SharePoint 2013 sur site (On-Premise) ou SharePoint 2013 Online (O365)
  • Avoir configuré votre service de recherche ainsi que la recherche de personnes
  • Avoir une référence aux librairies tierces suivantes : jQuery, jQuery.UI et jQuery.Ui.Autocomplete

Librairies tierce

Il y a quelque années, j’avais réalisé une composante permettant d’utiliser l’autocomplétion en utilisant la composante RadAutoCompleteBox de Telerik. Cette composante payante avait requis relativement beaucoup d’effort afin d’être intégré dans SharePoint en plus de nécessiter le déploiement et l’hébergement d’un service Web spécifique pour fournir les résultats de recherche.

Maintenant, il existe plusieurs librairies tierces gratuites permettant d’effectuer le travail en s’intégrant dans SharePoint beaucoup plus facilement et en interrogeant l’API REST de recherche natif. Une des librairies populaires est le plugin Autocomplete de jQuery.

Intégrer le plugin AutoComplete

Je m’inspire du code provenant du billet de Murad qui nous offre un bon point de départ pour intégrer le plugin. Le code intègre les librairies tierces requises pour cette démonstration en plus de fournir un champ texte pour effectuer la recherche. Il suffit donc d’insérer le code suivant dans une WebPart de type Éditeur de Script :

<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery.ui.autocomplete.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
//[...]
//Code retiré pour simplifier l'exemple
//[...]
<table>
<tbody>
	<tr>
		<td>REST Search</td>
		<td>
 		<div id="menu-container" style="width:600px">
			<input type="text" id="restSearch" size="50"/>
			</div>
		</td>
	</tr>
</tbody>
</table>

Construire une requête pour obtenir des résultats de recherche de personnes

Tout d’abord, il faut construire une requête sur l’API REST de recherche. Ce site est une excellente référence sur les divers points d’entrés ainsi que sur les paramètres disponibles pour construire notre requête.

Ex : https://<NomWebApplication>/_api/search/query?querytext=’lev*’&sourceid=’B09A7990-05EA-4AF9-81EF-EDFAB16C4E31’&clienttype=’Custom’

  • Le paramètre querytext représente le terme que l’on recherche
  • Le paramètre SourceId indique le GUID du résultat Source à utiliser pour l’exécution de la requête de recherche

Remarquez la propriété SourceId qui fait partie de la requête. On aurait pu utiliser le paramètre « ContentClass=urn:content-class:SPSPeople » à la place, mais SharePoint 2013 expose le SourceId des résultats. Le SourceId pour les résultats de personnes semble être le même pour toutes les installations soit « B09A7990-05EA-4AF9-81EF-EDFAB16C4E31 ». Alors je ne me sens pas coupable de hardcoder ce GUID.

On peut tester cette requête en l’exécutant directement dans le fureteur  qui nous affichera le résultat sous une forme XML :

rest_people_search_results_xml

Ajouter le code pour exécuter la requête et afficher les résultats de recherche de personnes

Afin de retourner des résultats de recherche de personne, il faut modifier le code initial afin de lancer un appel asynchrone lorsqu’un certain nombre de caractères seront saisie par l’utilisateur. La requête construite précédemment sera par la suite exécuté et finalement on affichera les résultats en dessous du champ texte recherche.

<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
 <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery.ui.autocomplete.css" />
 <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js">
 </script>

<script type="text/javascript">
 // Parse an item and create an title/value dictionary with all the properties available
 function getFields(results) {
 r = {};
 for(var i = 0; i<results.length; i++) {
 if(results[i] != undefined && results[i].Key != undefined) {
 r[results[i].Key] = results[i].Value;
 }
 }
 return r;
 }

 $(document).ready(function() {

 var autocomplete = $( "#restSearch" ).autocomplete({
 minLength: 3,
 source: function( request, response ) {
 $.ajax({
 beforeSend: function (request)
 {
 request.setRequestHeader("Accept", "application/json;odata=verbose;charset=utf-8");
 },
 url: "/_api/search/query?sourceid='B09A7990-05EA-4AF9-81EF-EDFAB16C4E31'&querytext='" + request.term + "*'",
 dataType: "json",
 success: function( data ) {
 response( $.map( data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results, function( item ) {
 return {
 fields: getFields(item.Cells.results)
 }
 }));
 },
 error: function( data ) {
 alert('search error');
 }
 });
 },
 // Run this when the item is in focused (not selected)
 focus: function( event, ui ) {
 //$( "#restSearch" ).val(ui.item.value );
 return false;
 },
 // Run this when the item is selected
 select: function( event, ui ) {
 location.href = ui.item.fields.Path;
 },
 appendTo: $('#menu-container')
 }).data( "uiAutocomplete" )._renderItem = function( ul, item ) {
 return $("<li>").append('<a>' + item.fields.PreferredName + '</a>' )
 .appendTo( ul );
 };
 });
</script>

<table>
 <tbody>
 <tr>
 <td>REST Search:</td>
 <td>
 <div id="menu-container" style="width:600px">
 <input type="text" id="restSearch" size="50"/>
 </div>
 </td>
 </tr>
 </tbody>
 </table>

Résultat :

rest_people_search_results

Dans de grandes entreprises on peut retrouver plusieurs personnes ayant le même nom  et prénom. Pour éviter la confusion, il est facile d’ajouter la photo, le titre ou la direction de la personne.

Pour s’y faire, simplement modifier la ligne suivante :

return $("<li>").append('<a><img style="margin-right:3px;top:3px;" src="/_layouts/15/images/'+ img +'">' + item.fields.Title + '</a>' ) .appendTo( ul );

Par ceci :

var hasPicture = item.fields.PictureURL;
var currentItem;
 if(hasPicture){
 currentItem = '<a><img src="' + item.fields.PictureURL + '"/>' + item.fields.PreferredName + ' - ' + item.fields.JobTitle + '</a>'
 }
 else{
 currentItem = '<a><img src="/_layouts/images/o14_person_placeholder_96.png"/>' + item.fields.PreferredName + ' - ' + item.fields.JobTitle + '</a>'
 }
return $("<li>").append(currentItem).appendTo( ul );

Résultat :

rest_people_search_results_with_img

Conclusion

On peut réaliser une fonctionnalité d’autocomplétion des résultats de recherches de personnes très rapidement en intégrant le plugin gratuit jQuery Autocomplete et en utilisant les API REST de recherche natif. Cette solution fonctionne pour les environnements SharePoint 2013 sur site (On-Premise) ainsi que dans SharePoint 2013 Online (O365). Le code ne nécessite pas de déploiement de solution et il pourrait facilement être amélioré pour ajouter toute autres propriétés que vous jugeriez pertinente (Ex : Département, intérêts, etc…).

Cliquez ici pour télécharger le code source

Citation

Murad Sæter. (2013, 20 février). Using jQuery UI autocomplete with the REST API to get search results in the search box [Billet de blogue]. Repéré à http://blogs.msdn.com/b/murads/archive/2013/02/20/using-jquery-ui-autocomplete-with-the-rest-api-to-get-search-results-in-the-search-box.aspx

Comment créer un service Web WCF (REST) personnalisé dans SharePoint 2013

Récemment, un collègue m’a demandé comment faire pour exécuter du code serveur dans un bouton du ruban. Je lui avait alors répondu : Le plus simple c’est de te faire une page aspx avec une WebPart contenant du code serveur. C’est comme si tu appelais un service web mais au lieu de cela c’est une page aspx avec des paramètres dans le querystring.

Ex : Lors du clique sur un bouton du ruban on appel une page avec des paramètres pour effectuer la modification d’un élément. Assumons que la page se nomme ModifierElement.aspx, alors il sera possible d’y accéder seulement à partir de sont chemin fixe : http://serveur/sites/site/web/pages/ModifierElement.aspx?Id=1

Dans le code du ruban (CustomAction), on peut seulement utiliser du code JavaScript (CSOM) et pour utiliser du code serveur on doit invoquer un événement via le bouton. Ces deux dernières méthodes comportent un certain niveau de complexité ainsi que des limitations.

L’approche de la page aspx est souvent utilisé pour sauver du temps lors du développement. Cependant, après quelques recherches je suis tombé sur une meilleure façon d’exécuter du code serveur en utilisant un Service Web WCF (REST) personnalisé hébergé dans SharePoint.

Comment faire un service Web (WCF) personnalisé ?

Les services Web natif de SharePoint peuvent être accédés à partir du chemin _vti_bin.  Lorsque l’on va développer notre service Web personnalisé il sera accessible via ce même chemin.

Ex : Assumons que le service Web personnalisé se nomme Service.svc alors il sera possible d’y accéder, entre autres, à partir des chemins suivants :

* C’est un avantage comparativement à la méthode de la page contenant une WebPart 

Étape 1 – Créer un projet Visual Studio 2012

  • Créer un nouveau projet à partir du modèle « SharePoint 2013 – Empty Project »
  • Nommer le projet « POC.SharePoint.WebServiceHelloWord »
  • Sélectionner « Deploy as a farm solution »

Étape 2 – Ajouter les références

  • Ajouter les références suivantes dans votre projet : Microsoft.SharePoint.Client.ServerRuntime 15.0.0.0 et System.ServiceModel 4.0.0.0

referenceWcf

Étape 3 – Ajouter un SharePoint Mapped Folder (ISAPI)

Le dossier ISAPI est le dossier spécial dans la « hive » SharePoint où tous les services WCF doivent être déployés. Ce dossier est associé au chemin « _vti_bin » dans IIS et ainsi les services déployés dans ce dossier peuvent être accédé par ce URL : http://serveur/_vti_bin/{NomService}.svc

Pour ajouter un nouveau Mapped Folder on sélectionne le projet et ensuitie on clique de droit -> ajouter -> SharePoint Mapped Folder :

mappedFolderWcf

Ensuite sélectionner le dossier ISAPI :

isapiWcf

C’est une bonne pratique de se créer un sous dossier spécifique à votre projet e.g.: « WebServiceHelloWord » .

Étape 4 – Définir le Service, le Contract et l’Interface

Dans le Mapped Folder « ISAPI » ajouter les fichiers suivants :

  • un fichier texte nommé « Service.svc » (Fichier du service lui même qui sera déployé dans le hive de SharePoint et qui sera appelé dans IIS)
  • un fichier Interface nommé « IService.cs » (Fichier contenant le contrat d’opération du service)
  • un fichier Classe nommé « Service.svc.cs » (Fichier contenant l’implémentation de l’interface du service)

Étape 5 – Définir le contenu du Service, du Contract et de l’Interface

Ouvrez le fichier Service.svc.cs et y insérer le code suivant :

using Microsoft.SharePoint.Client.Services;
using System.ServiceModel.Activation;

namespace POC.SharePoint.WebServiceHelloWord.ISAPI.WebServiceHelloWord
{
 [BasicHttpBindingServiceMetadataExchangeEndpoint]
 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
 public class Service : IService
 {
 public string HelloWorld()
 {
 return "Hello World de mon service WCF dans SharePoint 2013";
 }
 }
}

Ouvrir le fichier IService.cs et y insérer le code suivant :

using System.ServiceModel;

namespace POC.SharePoint.WebServiceHelloWord.ISAPI.WebServiceHelloWord
{
 [ServiceContract]
 public interface IService
 {
 [OperationContract]
 string HelloWorld();
 }
}

Ouvrir le fichier Service.svc et y insérer le code suivant :

<%@ ServiceHost Language="C#" Debug="true"
 Service="POC.SharePoint.WebServiceHelloWord.ISAPI.WebServiceHelloWord.Service, $SharePoint.Project.AssemblyFullName$"
 CodeBehind="Service.svc.cs"
 Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory,
 Microsoft.SharePoint.Client.ServerRuntime,
 Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

Étape 6 – Permettre à VS d’effectuer le remplacement des tokens dans un fichier *.svc

Dans le code du dernier fichier Service.svc qu’on a ajouté il y a une ligne contenant un jeton de remplacement (Token) : $SharePoint.Project.AssemblyFullName$

Si on ne fait rien on aura une erreur lors de la compilation. Il y a plusieurs façon de s’y prendre mais à mon avis la façon la plus élégante est de permettre à VS d’effectuer le remplacement de ces tokens pour les fichiers « *.svc ». J’appel cette technique la passe du coyote qui tousse!

Pour s’y faire, on doit effectuer un « Unload Projet » et ensuite un « Edit {NomDuProjet}.csproj ».

Ensuite trouver la ligne suivante :

<SandboxedSolution>False</SandboxedSolution>

Après cette ligne ajouter celle-ci :

<TokenReplacementFileExtensions>svc</TokenReplacementFileExtensions>

Sauvegarder le fichier et faire un « Reload project ».

Étape 7 – Compiler, déployer et tester le service WCF (REST) personnalisé

Une fois que vous aurez compilé et déployé votre service, vous pourrez le tester directement par son URL : http://serveur/_vti_bin/WebServiceHelloWord/Service.svc

testWcf

Cliquez ici pour télécharger le code source

Autres cas d’utilisations

Bien évidemment, le message retourné par notre fonction « HelloWorld » ne nous apporte rien de concret mais voici quelques exemples d’utilisation que l’on peut faire avec un service Web WCF (REST) personnalisé dans SharePoint :

  • Modifier les métadonnées d’un document (Ex: Ajouter un préfixe)
  • Exporter un rapport personnalisé en PDF
  • Modifier la sécurité d’un élément
  • Envoyer un document en pièce jointe d’un courriel
  • etc…

Conclusion

Utiliser un service Web WCF (REST) personnalisé dans SharePoint comporte plusieurs avantages comparativement à utiliser une page « aspx » avec une WebPart. D’une part, le service est accessible plus facilement via « _vti_bin » dans tout les sites et lorsqu’on utilise un service web WCF on envoie seulement le XML nécessaire au lieu d’envoyer tout le contenu HTML d’une page « aspx ».