Si vous avez l’erreur “The security validation for this page is invalid” [Sharepoint]

“The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.”

Si Sharepoint vous donne ce joli message d’erreur lorsque vous communiquez avec un de ses web services, alors il est possible que vous ayez oublié d’ajouter un header “SOAPAction” avec le nom du service associé.

Prenons l’exemple du web service lists.asmx et de l’action “UpdateListItems”. Si vous allez sur l’URL suivante http://votre_sharepoint/_vti_bin/lists.asmx?op=UpdateListItems vous verrez la SOAPAction qu’il faut définir (cliquez pour agrandir) :
Copie d'écran du web service lists.asmx

Dans l’exemple ci-dessus il faut donc définir l’header “SOAPAction” avec la valeur “http://schemas.microsoft.com/sharepoint/soap/UpdateListItems”.
Si vous utilisez l’AJAX de jQuery cela donnera quelque chose comme ça :

1
2
3
4
5
6
7
8
jQuery.ajax({
        type: "POST",
        dataType: "xml",
        data: soapEnv,
        beforeSend: function(xhr) { xhr.setRequestHeader('SOAPAction', 'http://schemas.microsoft.com/sharepoint/soap/UpdateListItems'); },
        contentType: "text/xml; charset=\"utf-8\""
    });

Si vous utilisez l’add-on Firefox Poster, alors utilisez l’onglet “Headers”.

Create a file into Sharepoint document librairies with the Copy.asmx web service [Javascript]

This is the English version of my previous article

EDIT: I’ve created a JavaScript API for Sharepoint that handles the file creation. Just look at http://aymkdn.github.com/SharepointPlus/symbols/%24SP%28%29.html#.createFile

Did you know it’s possible to create a file from scratch and to add it into a shared documents library of Sharepoint, and only with Javascript ?

To do it we’ll use the “copy.asmx” web service with the “CopyIntoItems” function.
If you check http://your_sharepoint/_vti_bin/copy.asmx?op=CopyIntoItems you’ll see that we have several details about the “CopyIntoItems” function. Unfortunately it’s very difficult to find any information regarding this on the Web, and specially for Javascript…

So, here is the solution to create a file, e.g. an Excel file (.xls) with a regular HTML table, and we’re going to save it to this library: “http://your_sharepoint/Shared Documents/” (Note: I’m using jQuery for the AJAX requests).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// The file content must be encoded into Base64. To do it I use the function available on my blog (http://blog.kodono.info/wordpress/2011/07/27/midi-code-encoder-decoder-en-base64-pour-javascript-programmation/)
function encode_b64(a,b,c,d,e,f){b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";c='=';for(d=f='';e&=3,a.charAt(d++)||(b=';=',e);f+=b.charAt(63&c>>++e*2))c=c<<8|a.charCodeAt(d-=!e);return f}
 
// "Upload" is the name of our function to do the job
// txtContent is a plain text, the content of our file
// destinationUrl is the full path URL to the document library (with the filename included)
function Upload(txtContent, destinationUrl) {
    var jsStream = encode_b64(txtContent);
    var soapEnv  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                  +"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                  +"<soap:Body>"
                  +"<CopyIntoItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">"
                  +"<SourceUrl>http://null</SourceUrl>"
                  +"<DestinationUrls><string>"+destinationUrl+"</string></DestinationUrls>"
                  +"<Fields><FieldInformation Type='File' /></Fields>"
                  +"<Stream>"+jsStream+"</Stream>"
                  +"</CopyIntoItems>"
                  +"</soap:Body>"
                  +"</soap:Envelope>";
    jQuery.ajax({
        type: "POST",
        dataType: "xml",
        data: soapEnv,
        beforeSend: function(xhr) { xhr.setRequestHeader('SOAPAction', 'http://schemas.microsoft.com/sharepoint/soap/CopyIntoItems'); },
        contentType: "text/xml; charset=\"utf-8\""
    });
}
 
Upload("<html><table><tr><th>Colonne 1</th><th>Colonne B</th></tr><tr><td>Total:</td><td>1500</td></tr></table></html>","http://your_sharepoint/Shared Documents/test.xls");

Then, when you’ll click on the new “test.xls” file, your web browser will want to open it with Excel. MS Excel should show you a warning message, but just click YES and you’ll see your table inside the sheet !

Of course you can create any type of files (.txt, .jpg, .doc, …) and with any content.

Related links:

Créer un fichier dans une librairie Sharepoint grâce au web service Copy.asmx [Javascript]

EDIT: J’ai créé une API JavaScript pour Sharepoint qui gère la création de fichier. Vous pouvez la consulter là : http://aymkdn.github.com/SharepointPlus/symbols/%24SP%28%29.html#.createFile

Saviez-vous qu’il est possible de créer un document de toute pièce et de l’ajouter dans une librairie (“Shared Document”) de Sharepoint seulement avec Javascript ?

Pour cela nous utiliserons le web service “copy.asmx” avec la fonction “CopyIntoItems”.
Si vous pointez vers l’adresse http://votre_sharepoint/_vti_bin/copy.asmx?op=CopyIntoItems vous remarquerez qu’on vous fournit un certain nombre de détails quant aux informations qu’il faut envoyer. Malheureusement c’est plutôt très mal documenté, surtout pour Javascript…

Voici donc la solution pour créer un fichier, par exemple un fichier Excel (en .xls) dans lequel on va mettre un tableau HTML banal et qui sera enregistré (dans notre exemple) dans la librairie “http://votre_sharepoint/Shared Documents/” (à noter que j’utilise jQuery pour la requête ajax).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// le contenu de notre fichier doit être encodé en Base64. Pour cela j'utilise la fonction disponible sur mon blog (http://blog.kodono.info/wordpress/2011/07/27/midi-code-encoder-decoder-en-base64-pour-javascript-programmation/)
function encode_b64(a,b,c,d,e,f){b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";c='=';for(d=f='';e&=3,a.charAt(d++)||(b=';=',e);f+=b.charAt(63&c>>++e*2))c=c<<8|a.charCodeAt(d-=!e);return f}
 
// Notre fonction qu'on va appeler "Upload"
// txtContent est du plain text qui est donc le contenu de notre fichier
// destinationUrl est l'URL complète vers la librairie où le fichier va être stocké (avec le nom du fichier à créer)
function Upload(txtContent, destinationUrl) {
    var jsStream = encode_b64(txtContent);
    var soapEnv  = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                  +"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                  +"<soap:Body>"
                  +"<CopyIntoItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">"
                  +"<SourceUrl>http://null</SourceUrl>"
                  +"<DestinationUrls><string>"+destinationUrl+"</string></DestinationUrls>"
                  +"<Fields><FieldInformation Type='File' /></Fields>"
                  +"<Stream>"+jsStream+"</Stream>"
                  +"</CopyIntoItems>"
                  +"</soap:Body>"
                  +"</soap:Envelope>";
    jQuery.ajax({
        type: "POST",
        dataType: "xml",
        data: soapEnv,
        beforeSend: function(xhr) { xhr.setRequestHeader('SOAPAction', 'http://schemas.microsoft.com/sharepoint/soap/CopyIntoItems'); },
        contentType: "text/xml; charset=\"utf-8\""
    });
}
 
Upload("<html><table><tr><th>Colonne 1</th><th>Colonne B</th></tr><tr><td>Total:</td><td>1500</td></tr></table></html>","http://votre_sharepoint/Shared Documents/test.xls");

Ensuite si vous cliquez sur le fichier “test.xls” nouvellement créé, votre navigateur va vouloir l’ouvrir avec Excel. Celui-ci va vous donner un warning, mais il suffit d’accepter et votre tableau va apparaitre dans votre Excel !
Bien sur on peut créer tout type de fichier (.txt, .jpg, .doc, etc) et avec le contenu que l’on souhaite.

Liens additionnels:

Transférer un compte Google vers un autre compte Google

Je vais vous expliquer comment j’ai procédé pour basculer toutes mes informations Google (GMail, GDoc, GTalk, GCalendar, ….) vers un autre compte Google.

Pour information, à partir d’Android 2.3.7 (en tout cas je l’ai constaté sur cette version), il est possible d’utiliser plusieurs comptes Google sur un même téléphone, et donc de choisir ce qu’on souhaite synchroniser. De même pour chaque application Android de Google, on peut facilement choisir quel compte utiliser. Cela peut-être pratique si vous avez acheté des articles sur le Market avec votre ancien compte et donc que vous souhaitez les conserver sans repayer.

Transférer ses emails GMail vers un autre compte GMail

Pour cela j’ai utilisé GMail Backup : commencez par sauvegarder tous vos emails sur votre ordinateur avec votre ancienne adresse GMail Une fois l’opération terminée, utilisez de nouveau l’application mais avec la nouvelle adresse GMail. Ensuite il suffit de cliquer sur “Restore”.
Les dates et les divers informations du courrier seront sauvegardées ! Et le logiciel vous remettra aussi vos labels !

Transférer ses contacts GMail vers un autre compte GMail

Cette fois Google vous facilite la vie. Allez dans Google Contact, cliquez sur “Plus” et sur “Exporter…”

Et dans votre nouveau GMail, faites pareil en choisissant cette fois “Importer…”. Et le tour est joué !

Transférer ses calendriers GCalendar vers un autre compte GCalendar

Là encore Google a tout prévu : allez dans les paramètres de votre calendrier (en cliquant sur la roue en haut à droite de la page), puis cliquez sur l’onglet “Agendas”. Vous verrez le lien “Exporter mes agendas”.
Et sur le nouveau GCalendar, vous n’avez plus qu’à utiliser le lien à coté : “Importer l’agenda”.

Transférer ses documents GDocs vers un autre compte GDocs

Cette fois vous aurez besoin du logiciel GDocBackup, et comme pour les emails, vous allez tout sauvegarder votre ancien compte sur votre ordinateur, puis dans votre nouveau compte il vous suffit de choisir “Importer fichiers…” :

Transférer vos flux RSS de Google Reader vers un autre compte Google Reader

Rendez-vous dans les paramètres de l’ancien compte Google Reader puis choisissez l’onglet Importer/Exporter. De là vous trouverez de quoi récupérer vos données.
Le problème : c’est que vous perdez là où vous en étiez dans votre lecture…

Réduire la taille d’une web font et bien plus encore…. [bookmark]

Le site FontSquirrel propose un outil très puissant qui va vous transformer votre font en tous les formats (woff, eot, ttf, svg, …), mais il vous propose aussi de réduire la taille de votre font pour une utilisation Web (ce qu’on nomme le “subsetting”). Par exemple si vous n’allez avoir besoin que des chiffres, il est dommage de télécharger une font de 500ko qui contient tous les caractères de tous les alphabets, alors qu’en ne conservant que les chiffres on pourrait tomber à 10ko.

Un outil à utiliser de toute urgence si vous devez traiter avec des web fonts !

Trouver l’heure et la date en Javascript d’un autre timezone [programmation]

Pour récupérer l’heure courante d’un autre timezone voici comment faire (ici je prends l’exemple de CST qui est UTC-5, c’est-à-dire -300 minutes) :

1
new Date(new Date(new Date().toUTCString()).setMinutes(-300));

Ensuite il faudra utiliser les fonctions getUTC* pour avoir les informations relatives à la nouvelle heure :

1
2
3
var dLocal = new Date(); // -> Thu Nov 03 2011 09:50:19 GMT+0100
var dOffset = new Date(new Date(new Date().toUTCString()).setMinutes(-300));
var offsetHours = dOffset.getUTCHours(); // -> 3

Envoyer un email à plusieurs personnes via un Workflow [Sharepoint]

Avec Sharepoint et les Workflow il est possible d’envoyer des emails à une personne (ou un groupe) en se basant sur un champs “Personne” de la Liste. Il est également possible d’envoyer un email à plusieurs personnes d’un coup grâce à ce même champs, mais en choisissant l’option “Sélection Multiple”.
Attention cependant: lorsque vous créez le Workflow qui va envoyer l’email, il ne va pas vous proposer le champs en question tant qu’il est en “Sélection Multiple” ! Pour que cela fonctionne, il faut désactiver la sélection multiple le temps de configurer le workflow, puis l’autoriser de nouveau.

C’est donc simplement l’interface utilisateur de Sharepoint Designer qui bloque, alors que c’est techniquement possible.

Plus d’informations : http://social.msdn.microsoft.com/forums/en-US/sharepointworkflow/thread/ebcb81ec-ba36-4a4c-bd01-26dc2c4d0913/

Supprimer les tags <script> d’une chaine de caractères [javascript]

Il suffit d’utiliser la chaine RegEx suivante :

1
2
3
var myText = 'blah blah <script type="text/javascript">foo=bar;</script>blah blah';
var myStripText = myText.replace(/<script.*?>[\s\S]*?<\/.*?script>/gi,"");
console.log(myStripText); // -> 'blah blah blah blah'

On peut également utiliser une expression régulière pour supprimer les liens javascripts :

1
2
3
var myText = 'blah blah <a href="javascript:alert(gniii)">foo</a>blah blah';
var myStripText = myText.replace(/javascript.*:[^"]*/gi,"");
console.log(myStripText); // -> 'blah blah <a href="">fooblah blah'

Revenir à l’actualité récente de Facebook suite à la mise à jour [Astuce]

Ces derniers jours Facebook a mis en place une nouvelle page d’accueil qui montre seulement les 20 dernières minutes des actualités récentes, et le reste dans un Top Story, assez moisi il faut bien le reconnaître…

Pour revenir à un système avec toutes les actualités récentes de ses amis, il suffit d’une petite astuce :

  1. Allez sur https://www.facebook.com/bookmarks/lists puis cliquez sur “Créer une liste” que vous pouvez nommer “Tout le monde” (ou “tous mes amis” ou “actualités récentes”) par exemple

  2. Maintenant cliquez sur « "Ajouter des ami(e)s" à cette liste pour voir leurs actualités », et choisissez tous vos amis (un par un….); pensez aussi à ajouter les Pages dont vous êtes fans pour continuer à suivre leurs actualités (en haut à gauche choisissez "Pages" au lieu d’ "Amis")
  3. Une fois terminé, vous aller voir “Tout le monde” (ou le nom que vous avez donné à la liste) dans la colonne de gauche au niveau de “Listes”
  4. Et voilà c’est prêt. Maintenant, lorsque vous voudrez voir l’actualité récente de vos amis, vous n’aurez qu’à cliquer sur ce “Tout le monde” dans la colonne de gauche.
    Vous pouvez aussi survoler ce “Tout le monde” avec la souris puis cliquer sur le petit crayon qui apparait à gauche et choisir “Ajouter aux favoris” pour être sûr de l’avoir de disponible facilement.

    Et le voilà de disponible dans vos favoris :

Aussi, n’oubliez pas d’ajouter vos nouveaux amis dans la liste “Tout le monde” à chaque fois pour être sûr de continuer à voir leurs actualités récentes.

Attention ! Si vous entrez un nouveau statut à partir de cette page, prenez en compte que ce statut pourra être vu par toutes les personnes de cette liste (c’est-à-dire tous vos amis). Cet avertissement vaut seulement pour ceux qui limitent leurs statuts à certains groupes.

Comment déboguer son code Javascript ? [programmation]

Évidemment vous pouvez utiliser Firebug (add-on Firefox) pour trouver les problèmes dans votre code, que ce soit des erreurs de syntax (syntax error) ou autre. Même s’il semble qu’avec la version de Firebug 1.8.x l’information fournie ne soit plus autant utile (mais espérons que ce ne soit que temporaire).

Il existe des sites web qui fournissent un débogage du Javascript, et mon préféré est http://www.javascriptlint.com/. Il vous montrera rapidement ce qu’il ne va pas dans ce que vous avez entré : oubli de parenthèse, de point-virgule, mauvaise déclaration, …

De plus si vous utilisez Notepad++ ou un autre éditeur, il est facile d’adjoindre la puissance de JSLint à votre programme préféré. Dans ce thread on vous explique tout.
En l’occurrence voici comment faire pour Notepad++ :

  1. Télécharger la version pour Windows, puis dézippez le fichier;
  2. Maintenant ouvrez Notepad++, puis dans le menu Plugins vous trouvez NppExec, et après Execute… (ou touche F6);
  3. Dans la zone qui apparait entrez la commande suivante (en supposant que vous ayez mis le fichier dézipppé dans “C:\Program Files\JavascriptLint\”) :
    "C:\Program Files\JavascriptLint\jsl.exe" -conf "C:\Program Files\JavascriptLint\jsl.default.conf" -process "$(FULL_CURRENT_PATH)"
  4. Cliquez sur “Save…” et donnez un nom à cette commande;
  5. Vous pouvez désormais utilisez JSLint directement dans Notepad++
  6. Dans le fichier jsl.default.conf vous trouverez les options et les warnings à supprimer