Edgar Maucourant - Expert / Formateur SharePoint

Aller au contenu | Aller au menu | Aller à la recherche

dimanche 4 mars 2012

SharePoint 2007 (et 2010 ?) : suppression d'un serveur de BDD impossible

Bonjour à tous,

Imaginons que vous n'ayez pas installé votre ferme SharePoint selon les bonnes pratiques, et qu'au lieu d'utiliser un alias SQL Server vous ayez directement saisi le nom du serveur pour la création des services (c'est ballot mais c'est courant...).

Imaginons maintenant que vous souhaitiez refaire les choses bien et que vous recréiez les services avec un alias (c'est un bon consultant ça ! oh oui un bon consultant...).

Il est probable qu'ensuite vous souhaitiez supprimer le serveur de BDD référencé dans la section "Servers in farm".

Sage décision, le ménage ça fait toujours du bien (ma femme m'a obligé à mettre cette phrase...), cependant lorsque vous cliquez pour supprimer le serveur vous obtenez le message suivant :


An object in the SharePoint administrative framework, "SPDatabaseServiceInstance Name=NOMINSTANCE Parent=SPServer Name=NOMSERVEUR", could not be deleted because other objects depend on it. Update all of these dependants to point to null or different objects and retry this operation. The dependant objects are as follows :

Grosso modo, il existe des objets dépendant de celui-ci, et SharePoint ne peut pas le supprimer. Cependant la section listant les objets concernée est vide !! (Bizarre ça ne m'étonne même plus, je dois être trop habitué à SharePoint...)

Après un rapide tour sur Internet, vous trouvez un certain nombre de posts qui vous encouragent à aller faire une requête sur la base de données pour voir les objets dépendants et à les supprimer, par exemple : http://www.mylifeinaminute.com/2008/07/23/manually-removing-servers-in-moss-2007/

Pas de chance, cette requête ne retourne rien... On aurait pu s'en douter puisque c'est sûrement la même requête qui a été utilisée dans le message d'erreur ci-dessus.

En allant un peu plus loin vous pourriez tomber sur un post comme celui-ci : http://www.jeremytaylor.net/2010/01/09/sharepoint-moss-shared-services-ssp-delete-unprovisioning/ qui vous encourage à supprimer directement les objets par l'utilisation de STSADM, ce qui semble plus propre mais revient au même : la suppression d'une ligne directement dans la base. Pas de chance là également car l'exécution de cette commande vous renvoie exactement le même message que précédemment...

Dans votre quête de connaissance, vous continuez à chercher et tombez sur ce post : http://sharepointwillem.blogspot.com/2010_06_01_archive.html. Cette fois-ci on va encore plus loin dans le risque pour modifier temporairement la structure de la base de données SharePoint....(L'aaaaaamour du risque, Jonathan et Jennifer... tout ça, tout ça)


STOP !!!!


Bon honnêtement, là j'ai pas pu, je me suis dit qu'il devait y avoir un autre moyen... Et en regardant les contraintes de clés étrangères que le post précédent expliquait comment faire sauter (tout en disant qu'il ne faut pas le faire :o/), je me suis rendu compte qu'il y avait une autre forme de dépendance plus implicite (parce que non indiquée dans la table "dependencies") : la relation Parent / Enfant. En effet les tables des Objets SharePoint donne pour chaque objet quel est l'id de son parent (dont il dépend donc).

J'ai donc fait une recherche rapide sur les objets dont le parent est mon instance SQL Server (après avoir récupéré son Id), et j'ai trouvé le problème : la base de données du service de recherche d'aide WSS était encore stockée sur cette instance... Après avoir redéployée ma base de données du service de recherche d'aide via mon alias, j'ai pu supprimer ma référence de serveur sans soucis...

Ce cas illustre encore une fois le risque de suivre les actions données sur Internet, surtout si celles-ci vont à l'encontre des bonnes pratiques : on ne doit pas toucher aux bases SharePoint !!! Microsoft ne supporte même pas les requêtes SELECT sur ces bases, il ne s'agit donc pas juste de modifier la base, mais rien que lire les données de cette base en dehors des API SharePoint n'est pas supporté... Notez que pour SharePoint 2010 il me semble avoir lu que MS supporte la lecture, mais toujours pas évidemment l'écriture en direct dans les bases (sauf peut-être celle de logging, à vérifier)


Bon code à tous,
Edgar


Note : les plus perspicaces d'entre-vous se seront rendu compte que ma requête pour retrouver les objets parent n'est donc pas supportée... Gardez cela à l'esprit si vous suivez cette démarche (bon en même temps je ne pense pas que cela gêne quoi que ce soit sur la table Objects...).

mercredi 30 juin 2010

NFTInside recrute Consultant(s) et / ou formateur(s) SharePoint Technique ou fonctionnel

Bonjour,

Fort d'une activité soutenue et grandissante depuis maintenant plus de 2 ans, nous recherchons un ou plusieurs collaborateurs afin de renforcer nos équipes de consultants et de formateurs SharePoint. Vous trouverez ci-dessous un descriptif de poste. Si vous êtes intéressé(e) envoyez-moi votre candidature à edgar@nftinside.com.

Offre de poste : Vous avez envie d’intégrer une équipe où vous pourrez vous exprimer, et montrer vos qualités ?

NFTInside, jeune société (2008) de conseil, d’expertise et de formation sur SharePoint et InfoPath recherche un ou plusieurs collaborateurs (H/F) pour renforcer son équipe de consultants et de formateurs. Nous recherchons des profils techniques et / ou fonctionnels. En fonction de vos compétences et de vos envies vous serez amené(e),

Pour les profils techniques à :

  • Réaliser des implémentations de SharePoint (installation, déploiement, paramétrage,…)
  • Réaliser des développements de composants ou de portails pour SharePoint
  • Conseiller nos clients sur la mise en œuvre de solutions SharePoint, ou faire des audits de plate-forme.
  • Faire des formations Développeurs et / ou Administrateurs selon votre affinité avec le métier de formateur.

Pour les profils fonctionnels à :

  • Accompagner nos clients pour définir leurs besoins, et mettre en place une bonne gouvernance.
  • Paramétrer ou aider nos clients à paramétrer leurs sites collaboratifs et / ou de publication
  • Former les utilisateurs finaux à l’utilisation et le paramétrage d’un site SharePoint

Notre force est la relation de confiance que nous entretenons avec nos clients grâce à la qualité de nos prestations. Nous recherchons donc avant tout des collaborateurs(trices) qui aient un savoir-être autant qu’un savoir-faire. Si vous êtes motivé(e), consciencieux(se), autonome, force de proposition, votre profil nous intéresse !

Edgar Maucourant Directeur NFTInside

lundi 30 novembre 2009

Limite des 2000 éléments à qui s'applique-t-elle ? [MAJ : 03/02/2010]

Bonjour à tous,

MAJ du 3 Février 2010 : je reviens sur la conclusion de cet article qui est en partie erronée.

Pour les utilisateurs finaux, il est important de garder dans tous les cas des vues (affichages) dont le nombre total d'éléments (toutes pages confondues) soit inférieur à 2000 éléments (environ ça peut être un peu plus ou un peut moins).

En effet ce que ne montre pas le test ci-dessous c'est que lorsque beaucoup d'utilisateurs exécutent des affichages renvoyant plus de 2000 éléments au total, le serveur pourrait être très rapidement surchargé même si chaque page ne renvoit que 100 éléments. La gestion d'un nombre maximum d'éléments par page (paging) permet de reduire cette surcharge mais ne l'annule pas. Dans les résultats ci-dessous dès que l'on dépasse 500 éléments par page les performances se réduisent essentiellement à cause du temps de transfert des informations du serveur vers le navigateur et du temps nécessaire au navigateur pour interpreter et mettre en page ces informations. Cependant la surchage sur le serveur est importante à partir du moment où l'on dépasse cette fameuse limite des 2000 éléments, essentiellement à cause de contraintes sur les bases de données SQL Server (pour les amateurs de données techniques lire cet article : http://sharepoint.microsoft.com/blogs/GetThePoint/Lists/Posts/Post.aspx?ID=162)

Il existe donc que deux solutions, mettre moins de 2000 éléments par niveau (racine, dossiers, sous-dossiers,...) ou utiliser des vues avec des filtres renvoyant moins de 2000 éléments (moins efficace que la répartition par dossiers mais permet d'améliorer les performances tout de même).

Dans le deuxième cas, il est important de noter que la première colonne utilisée pour le filtre doit être indexée pour améliorer les performances (les indexes sur les autres colonnes ne sont pas pris en compte lors de la requête). Il est important également de noter que si vous utilisez un filtre à plusieurs colonnes, seuls le nombre d'éléments renvoyés par le filtre sur la première colonne est important. Ainsi si je créé un affichage utilisant un filtre du type "Service égale à DRH ET Créé par égale à Jean Dupont" si la colonne Service contient plus de 2000 éléments avec la valeur DRH, le filtre ne sera pas efficace même si le résultat final (les deux filtres associés) renvoit moins de 2000 éléments !

Comme quoi la gestion des performances est un sujet complexe, j'espère que cet éclaircissement vous sera utile lors de la gestion de grandes listes

Pour plus d'infos : http://office.microsoft.com/en-us/sharepointtechnology/HA101736671033.aspx (article en anglais, je n'ai pas trouvé malheureusement d'équivalent en français).

Fin de la MAJ

On entend régulièrement (y compris de ma part) que les listes SharePoint ont une limite de performance aux alentours de 2000 éléments (a visto de naz...), ce qui est vrai, mais depuis quelques temps déjà je me demandais dans quelle mesure cette perte de performance s'appliquait. En effet la plupart des articles que j'ai lu parlent d'une perte de performance à partir de 2000 éléments par conteneur (dossier) ou par vue, mais ce dernier terme n'est pas clair pour moi.

Une vue peut afficher 2000 éléments au total mais répartis par page de 100 éléments (le défaut), dans ce cas est-ce le nombre d'élément par page ou pour la vue globale dont il faut tenir compte ?

De plus à qui s'applique cette consigne ? Aux utilisateurs finaux ? Aux développeurs ? Aux deux ?

Afin d'avoir enfin la réponse à ces questions j'ai testé différents cas et j'ai calculé les temps d'affichage des pages (oui je sais je suis dans ma phase statistiques en ce moment...). Je me suis donc contenté de tester la partie utilisateurs finaux, car des articles pour les développeurs ont déjà été écrit (un lien vers l'un deux est donné en fin d'article).

Lire la suite...

dimanche 29 novembre 2009

Forum de discussion attention aux pièces jointes orphelines... (Application CodePlex inside...) MAJ 02/12/09

Bonjour à tous,

EDIT 02/12/2009 : La CU d'Octobre semble régler ce problème, cependant je n'ai pas encore testé ce patch, et je ne sais pas si une fois appliqué cela supprime toutes les pièces jointes orphelines existantes ou si cela permet juste de ne plus en créer, pour plus d'infos : http://support.microsoft.com/kb/975002/en-us (3ème puce)

En travaillant sur un projet pour Alti (www.alti.fr, un peu de pub ça ne fait jamais de mal...), je me suis rendu compte que lorsque l'on supprime un sujet de discussion dans un forum sur un site SharePoint, les pièces jointes associées à ce sujet ne sont pas supprimées ! Elles deviennent des pièces jointes orphelines, et il n'est pas plus possible de les supprimer par l'interface utilisateur ou le modèle objet.

Lire la suite...

dimanche 26 avril 2009

SharePoint, nom interne, nom d'affichage et URL

Bonjour à tous,

Cette fois encore je vais écrire une série de posts qui traitent d'un sujet commun mais que je préfère écrire en plusieurs fois pour rendre la lecture plus simple. Chaque post traitant d'une partie du sujet indépendante des autres.

Ce premier post traitera des noms intenes, des noms d'affichages et des URLs dans SharePoint, le second traitera de quelques limites fixées de l'outil SharePoint sur ces éléments (et il arrivera bientôt).

SharePoint est un progiciel, et qui dit progiciel dit paramétrage à outrance. Le progiciel étant la volonté d’avoir un outil à la fois très générique pour s’adapter au plus grand nombre et tout en même temps assez spécifique (vertical dit-on dans le métier) pour permettre une mise en œuvre rapide (vous sentez le paradoxe ?). De plus dans la globalisation du travail à laquelle nous faisons face, SharePoint se devait d’être multilingue.

"Jusque-là aucun problème ?" me direz-vous.

Et bien si, ceci est un problème car développer et paramètrer un environnement entièrement polymorphe (dont les noms et champs peuvent changer tout le temps) n’est pas du tout envisageable. Or un progiciel a besoin d'être polymorphe pour réellement s'adapter au métier et à l'organisation des clients.

D’un autre côté, fixer le nom des champs pour l’intégralité de l’application n’est pas envisageable non plus !

Imaginez : créer une colonne dont le nom serait fixé à l’avance et que vous ne pourriez pas changer, type : data1, data2, data3,… Bonjour l'horreur pour la mise en oeuvre...


Alors que faire ?

Recourir aux noms internes pardi ! Ainsi beaucoup d'éléments dans SharePoint possèdent un nom interne (qui ne varie pas) et un nom d’affichage qui lui peut varier à tout moment. Certains éléments comme les sites ou les listes possèdent eux plutôt une URL (qui fait office de nom interne) et un nom d'affichage.

Ainsi à présent nous avons un champ interne dont le nom ne varie pas (et donc auquel nous pouvons faire référence sans risque) et un nom d'affichage qui peut varier et s'adapter au contexte, à la langue, au grés et envies de l'utilisateur...

"Tout ça c’est bien beau", me direz-vous, "mais encore une fois beaucoup de texte et toujours pas de problème à l'horizon..."

Et encore une fois votre optimiste fait chaud au coeur mais vous conduira droit à votre perte (de cheveux dans ce cas...). Car le soucis c’est que SharePoint vous a masqué (légèrement) qu’un tel nom interne existait !!! Et surtout qu'il ne supportait pas les caractères spéciaux et espaces !

 

(Sentez-vous la tension monter maintenant ?)

 

Disgression 1 : Bon, soyons honnête, l’apprentissage de SharePoint n’est pas forcément des plus aisé, et si au départ on parlait de champs internes et de noms d'affichage certains se jetteraient par les fenêtres. C'est pourquoi souvent cette notion est passée sous silence. Cependant c'est très important de bien comprendre le fonctionnement de ces noms comme nous allons le voir à présent.

Donc comme je le disais, un des premier soucis auquel on peut être confronté avec ce nom interne c'est qu'il n'accepte pas les caractères spéciaux ni les espaces, et qu'il les remplace donc par des équivalents.

Ainsi :

  • "espace" devient _x0020_
  • "é" devient _x00e9_
  • "è" deivent _x00e8_
  • "'" (apostrophe) devient _x0027_
  • ...

Ce qui rend la lecture un peu fastidieuse car le champ : "Interlocuteur demandé" devient "Interlocuteur_x0020_demand_x00e9_"

De plus lorsque ce nom doit être affiché dans une URL, le sous-tiret bas (underscore : _) est remplacé par des %5f et devient donc : "Interlocuteur%5fx0020%5fdemand%5f00e9%5f", ce qui est franchement illisible...

Pire ces remplacements allongent la taille du nom interne de l'élément, or ce nom interne a souvent une taille maximum et sera tronqué en cas de dépassement (voir prochain article pour ce problème...).


"Hé là l'ami, arrête un peu ton char, j'ai jamais vu de champs nom interne et nom d'affichage dans SharePoint..."

Je ne sais qui a lancé cette remarque très judicieuse mais grand bien lui en a pris car c'était justement le sujet de mon prochain chapître...(Et hop une transition rondement menée, une !)

En effet, rares sont les pages de paramètrage dans SharePoint qui font état de ces deux noms, cependant ils existent (si si croyez moi monsieur l'agent je les ai vus !!!).

Et en voici donc des exemples :


A - Colonnes et colonnes de site

J'ai groupé ces 2 champs car leur comportement est identique. Ils sont sûrement les éléments dont les noms interne et d'affichage sont les moins visibles.

Voici donc un petit exercice...

1 - Création d'une colonne

Rendez-vous dans une liste quelconque et créez une colonne : "Interlocuteur demandé" de type texte :

1.png

2.png
Cliquez sur les images pour agrandir

Laissez les valeurs par défaut puis valider votre saisie. Vous devriez obtenir ceci (ici dans une liste personnalisée)

3.png
Cliquez sur l'image pour agrandir


2 - Visualisation du nom interne

Cliquez sur votre champ et regardez dans l'url la section après "&field=". Ceci est le nom interne de votre champ, vous voyez que ce n'est pas très lisible.

4.png
Cliquez sur l'image pour agrandir

Sachant que vous aurez parfois à faire référence à ce nom dans votre code ou paramètrage (comme pour la recherche par exemple), c'est pas gagné !


3 - Modification du nom d'affichage

Tant que vous êtes dans la page de modification, profitez-en pour modifier le nom de votre champ de "Interlocuteur demandé" en "Correspondant".

5.png
Cliquez sur l'image pour agrandir

Valider votre modification, votre nom de champ a changé mais ici ce n'est que le nom d'affichage

7.png
Cliquez sur l'image pour agrandir


4 - Visualisation du nom interne et d'affichage

Si vous retournez dans la page de modification vous voyez que le nom d'affichage du champ a été changé mais pas le nom interne.

6.png
Cliquez sur l'image pour agrandir

/!\ Attention : pour une colonne il n'est pas possible de changer le nom interne d'un champ, celui-ci est fixé à partir du nom d'affichage lors de la création du champ selon les règles précisées plus haut.

Conclusion : à la création de votre champ il faut penser à d'abord créer le nom interne (sans caractères spéciaux, ni espace) puis modifier le nom du champ pour lui donner le nom voulu. Ainsi pour notre champ d'exemple nous aurions d'abord créé le champ avec le nom : "InterlocuteurDemande" puis serions venu modifier le nom en "Interlocuteur demandé"



B - Listes et bibliothèques

Pour les listes et bibliothèques le nom interne correspond au nom utilisé pour composer l'URL (adresse) de la liste. Voici donc un exercice pour voir le comportement de SharePoint dans ce cas

1 - Création d'une nouvelle liste

Créez une nouvelle liste de type "Liste personnalisée" et appelez la : "Ma liste personnalisée"

8.png
Cliquez sur l'image pour agrandir


2 - Visualisation de l'URL

Une fois votre liste créée, regardez l'URL et vous verrez que le caractère "é" contenu dans "personnalisée" a disparu (car les caractères spéciaux sont supprimés par SharePoint pour les URLs), de plus pour être conforme à la norme URL, les espaces sont remplacés par un %20

9.png
Cliquez sur l'image pour agrandir


3 - Modification du nom de la liste

Allez dans les paramètres de la liste pour modifier son nom

11.png
Cliquez sur l'image pour agrandir

Remplacer le nom "Ma liste personnalisée" par "Ma liste à moi" et validez.

10.png
Cliquez sur l'image pour agrandir


4 - Visualisation du nom de la liste

Votre liste à bien changée de nom d'affichage

12.png
Cliquez sur l'image pour agrandir

Mais l'URL continue d'afficher le premier nom (le nom "interne")

13.png
Cliquez sur l'image pour agrandir


/!\ Attention : Comme pour les colonnes il n'est pas possible de modifier le nom interne (l'URL) d'une liste. On peut cependant copier la liste vers une autre destination (une autre URL, donc un autre nom interne) et supprimer la première liste.

Conclusion : comme pour les colonnes, pensez à créer d'abord votre liste avec le nom interne désiré puis changez son nom vers le nom d'affichage voulu.



C - Les sites

Les sites fonctionnent de la même manière que les listes sauf que l'URL du site peut-être fixée lors de la création du site et en modification.

1 - Création du site

14.png
Cliquez sur l'image pour agrandir

2 - Modification du site

En passant par les paramètres du site, dans la section "Titre, description et icône"

15.png
Cliquez sur l'image pour agrandir

On peut modifier cette URL après que le site soit créé (mais attention aux liens pointant sur cette "ancienne" URL)

16.png
Cliquez sur l'image pour agrandir

Conclusion : Penser à créer votre site avec une URL explicite et lisible, en remplaçant les espaces par des sous-tirets bas (underscore), et en ne mettant pas de caractères spéciaux.

Disgression 2 : Si vous vous dîtes que l'URL n'est pas importante car personne ne la lit, demandez-vous alors pourquoi on ne met pas que des URLs du type http://152650/121321564/?sddsfd122... Qui seraient plus simples à gérer côté code... L'URLs est lue bien plus souvent qu'on ne le croit par les visiteurs pour vérifier qu'ils se trouvent au bon endroit.



D - Cas spécial 1: Les vues (affichages)

Les vues représentent un cas à part car elles sont à mi-chemin entre les listes et les sites : on ne peux fixer leur URL à la création (qui est déduit du nom de la vue), mais on peut le faire à la modification

1 - Création d'une vue

18bis.png

17.png

18.png
Cliquez sur les images pour agrandir

Le résultat dans l'URL est le suivant

19.png
Cliquez sur les images pour agrandir

2 - Modification d'une vue

Au contraire des listes on peut modifier l'URL d'une vue en modification (comme pour les sites)

20.png

21.png
Cliquez sur les images pour agrandir

J'avoue que je suis un peu perplexe sur la démarche... Mais c'est ainsi.

Conclusion : Pensez à modifier l'URL de vos vues après création pour quelles soient plus explicites et lisibles, en remplaçant les espaces par des sous-tirets bas (underscore), et en ne mettant pas de caractères spéciaux.



E - Cas spécial 2 : Les types de contenu

Les types de contenu sont eux aussi un cas à part car ils n'ont pas à proprement parlé de nom interne, ils disposent cependant d'un ID qui est créé automatiquement à partir de l'ID du type de contenu dont il hérite (si cela vous semble nébuleux, passez votre chemin car l'explication de la création d'un type de contenu pourrait largement dépasser la taille de cet article déjà conséquent :D )

22.png
Cliquez sur l'image pour agrandir

Ici l'ID est visible dans l'URL en bas et suit le paramètre "?ctype="

/!\ Attention : Cet ID n'est modifiable ni à la création (à moins de créer son type de contenu avec une feature), ni en modification.


Conclusion générale:

Voilà, j'espère que ceci vous permettra de mieux comprendre le fonctionnement de SharePoint sur l'attribution des noms internes et des URLs. Ceci est souvent source de problème lors de développement car certains objets font référence aux noms internes, aux noms d'affichage ou aux deux... C'est aussi un problème pour du "simple" paramètrage, par exemple si vous créez de nouvelles propriétés gérées dans le moteur de recherche de MOSS pour créer de nouvelles étendues de recherche, le mappage de la propriété gérée vers un champ se fait sur le nom interne...

D'une manière générale il est important de garder des noms internes propres et courts car la limite se situe à 32 caractères maximum. Mais ceci fera l'objet d'un prochain article (et hop voici comment je vous tiens en haleine pendant la pub...)

Bon code à tous !

vendredi 13 mars 2009

Attention à la longueur des URLs des sites WSS (et MOSS ?)

Bonjour,

Un hotfix vient de sortir pour corriger un problème qui peut se réveler critique pour vos fermes SharePoint.

En effet de base WSS ne supporte pas d'URL de plus de 64 caractères pour les sites, prefixe http(s):// compris. Soit pas plus de 56 ou 57 caractères pour la partie intéressante de l'URL (suivant le protocol).

Ce qui est troublant et potentiellement très dangereux c'est que WSS vous laisse créer des sites avec des URLs plus longues mais ne les restaurera pas au cas où vous devriez utiliser une de vos sauvegardes !!

Heureusement un hotfix vient d'être mis à disposition. Vous pourrez trouver plus d'infos à cette adresse :

http://kbalertz.com/960487/Windows-SharePoint-Service-cannot-restored-header-length-greater-characters.aspx

Attention cependant une fois le hotfix appliqué vous n'aurez pas 255 caractères disponibles, comme le prévoit le standard Internet, mais 136 maximum (c'est déjà mieux que 64).

L'annonce précise que le problème se pose pour WSS 3.0 et non pour MOSS, mais il y a fort à parier que le problème est identique sur cette plate-forme également...

Bon code à tous !

mercredi 11 mars 2009

Vue en mode feuille de données (Access Web DataSheet) et répertoires : attention !

Bonjour à tous,

Ce post fait suite au précédent (non ??? si si) sur le problème des répertoires et des éléments dans les listes SharePoint.

Pour l'édition en masse des éléments dans les listes SharePoint il existe le mode "feuille de données" qui permet grâce à un composant ActiveX de voir le contenu de la liste au travers d'une interface type 'Microsoft Access'. Ce mode fonctionne très bien pour l'édition y compris avec les répertoires. Ainsi lorsque je me déplace dans un répertoire je ne vois que les éléments de ce répertoire dans la feuille de données, ce qui est parfait.

"Et donc ?" ce disent les plus perspicaces d'entre vous...

Et donc, le problème vient d'ailleurs (comme la vérité...ouais facile je sais...). Le soucis c'est lors de l'ajout de nouveaux éléments. Dans ce cas le comportement est plutôt frustrant puisque peu importe où je me trouve dans la liste les éléments sont créés à la racine...

Après plusieurs recherches et tentatives diverses et infructueuses, je me suis résolu à faire un gestionnaire sur l'évènement ItemAdded qui me permet de déplacer mon élément dans le bon répertoire en fonction de la valeur d'un champ de l'item (oui je sais c'est moche mais là je ne savais pas vraiment quoi faire d'autre à part changer complètement le développement...).

Voici donc le gestionnaire d'évènement :

public override void ItemAdded(SPItemEventProperties properties)
{
   using(SPWeb web = properties.OpenWeb())
   {
      SPListItem item = properties.ListItem;
      SPFile dummyFile = web.GetFile(item.Url);
      this.DisableEventFiring(); 
      dummyFile.MoveTo(web.Url + "/Lists/" + properties.ListTitle + "/" + item["RepName"].toString() + "/" + item.ID + "_.000");
      this.EnableEventFiring();
   }
}

A présent mes créations d'éléments au travers des feuilles de données fonctionnent correctement, mais je n'ai pas testé cette action sur une montée en charge importante donc le code est "fournis tel quel" sans garantie aucune :p

Bon code à tous !

PS : 3 posts dans la même journée je viens de péter mon record :)

Déplacement d'un SPListItem dans un répertoire d'une SPList

Bonjour à tous,

Quand il s'agit d'organiser l'information dans des bibliothèques de documents ou des listes SharePoint, il vaut mieux recourrir à des Content Types qu'utiliser des dossiers. Cependant parfois il est tout de même nécessaire d'utiliser des dossiers, notamment quand on nombre important d'items seront à terme stockés dans la liste (à cause de la fameuse barrière des (environ) 2000 items et de la chute de performance induite).

Le soucis lorsque l'on travaille avec des dossiers c'est que la création et le déplacement des éléments depuis le code SharePoint ce n'est pas si simple. On trouve un peu partout sur le net des exemples et des articles pour la création d'éléments dans une bibliothèque ou une liste (c'est la même procédure), par contre pour le déplacement c'est pas la même histoire.

Dans le cadre d'une bibliothèque le problème est assez simplement résolu via l'utilisation du SPFile associé à l'item (SPLIstItem.File) et plus précisement de la méthode MoveTo de cet objet. Par contre dans le cas d'une liste la propriété SPFile de l'objet SPListItem est null, donc impossible de faire le transfert...

Impossible ? non ! Un petit village d'irreductibles développeurs SharePoint (et bloggeurs) a percé le secret de ce déplacement. La méthode est pour le moins inattendue, complètement non documentée (à ce jour je n'ai trouvé qu'un post sur tout le net qui en parle) et très franchement capillotractée !!!

En réalité, en interne même pour les éléments d'une liste il existe bien un objet SPFile, mais celui-ci n'est tout simplement pas associé à l'item via la propriété File... Il faut le récupérer en utilisant la méthode GetFile() de l'objet SPWeb. Une fois que l'on a une référence à cet objet on peut utiliser la méthode MoveTo. Mais là aussi il y a une subtilité, il faut utiliser une URL de destination un peu particulière : URLduSite/Lists/NomListe/Rep/itemID_.000

Oui, oui vous avez bien vu "ID_.000", ce n'est pas très éloquent comme syntaxe mais cela fonctionne (ça sent un peu la bidouille quand même... si quelqu'un a une autre méthode...)

Voici donc un exemple de code (qui suppose que vous ayez déjà récupéré un SPListItem nommé item) :

using(SPWeb web = item.Web)
{
    SPFile dummyFile = web.GetFile(item.Url);
    dummyFile.MoveTo(web.Url + "/Lists/" + item.ParentList.Title + "/NomduRepertoire/" + item.ID + "_.000");
}

Et hop, votre item est transféré dans le bon répertoire, mais j'avoue quand même que cette technique me semble douteuse et j'émets les plus vives craintes sur la pérennité d'une telle méthode avec la future version de SharePoint (2010 ?). En attendant cela fonctionne et m'a tiré une belle épine du pied... (voir le prochain post...)

Bon code à tous !

CustomSiteAction.xml pour site de publication : fichier de ressource obligatoire !

Bonjour à tous,

La plupart des développeurs .Net le savent bien, lorsqu'il s'agit de faire des sites multilingues, en dehors des fichiers de ressources point de salut ! C'est encore plus vrai lorsque vous travaillez avec les fichiers CustomSiteAction.xml, CustomQuickAccess.xml ou CustomEditingMenu.xml.

Ces fichiers que vous pouvez trouvez dans le répertoire EditingMenu de la gallerie de page maîtres (lorsque le site est un site de publication) servent respectivement à modifier

  • le menu "Actions du site" (pour un site de publication),
  • la barre d'outils de modification de page (appelé aussi Authoring Console en anglais)
  • et enfin les menus de cette même barre (Page, Flux de travail, Outils,...).

Vous pouvez y ajouter, remplacer ou supprimer des entrées grâce à des noeuds "ConsoleNode".

Tout ce passe bien tant que vous n'utilisez pas directement d'accents ou de caractères autres que ASCII dans le fichier. En effet le fichier est au format XML mais ANSI par défaut. Si vous indiquez un caractère accentué (par exemple dans une description de menu) le fichier n'est plus conforme (et refuse de s'afficher dans IE par exemple). De plus si vous tentez de l'insérer tel quel dans SharePoint vous obtiendrez un joli message : "L'index se trouve en dehors des limites du tableau" (notez au passage la pertinence du message d'erreur).

"Qu'à cela ne tienne" me diront les plus aguérris, "Enregistre donc ton fichier en UTF-8 !" Et d'autres de rajouter : "banane !"

"Oui mais," rétorquerais-je (pratiquement du tac au tac, le temps de finir mon pain au chocolat...), "là c'est SharePoint qui n'est plus d'accord", il nous renvoit d'ailleurs ce message (encore une fois très explicite...) : "Le noeud spécifié ne peut pas être inséré comme enfant valide de ce noeud, car le noeud spécifié n'est pas du type correct"

"Mais crévindieu" s'exclament-t-alors les plus aguerris de naguerre, "comment qu'cé ti qui font chez Microsoft pour n'en n'avoir des accents dans leurs descriptions, eux ?".

La réponse est simple : fichier de ressource !

En l'occurence le fichier cms.resx que vous pouvez trouvez dans le répertoire "c:\inetpub\wwwrroot\cheminversvotrewebapp\App_GlobalResources\".

Vous savez donc maintenant ce qu'il vous reste à faire... Non ? Et bien, ajouter un nouveau fichier de ressource que vous déploierez grâce à une solution (en utilisant un noeud : ApplicationResourceFile) et faire référence à cette ressource dans vos fichiers de configuration, et vous voilà à présent roi de la modif des menus d'un site de publication.

Bon code à tous !

samedi 21 février 2009

VSeWSS 1.3 CTP : beaucoup de nouveautés et compatibles x64 :)

Bonjour à tous,

Un message rapide pour vous dire que les Visual Studio extensions for WSS 1.3 en version CTP (Community Technology Preview) sont disponibles à cette adresse :

http://www.microsoft.com/downloads/details.aspx?FamilyID=b2c0b628-5cab-48c1-8cae-c34c1ccbdc0a&DisplayLang=en

J'avais été assez déçu lors de la release de la version 1.2 qui apportait le support pour Visual Studio 2008 mais pas en version x64. Cette version préliminaire 1.3 montre que Microsoft a travaillé dans ce sens, ce qui ne peux que me ravir :p

Beaucoup d'améliorations en vue dans le descriptif. Je n'ai pas encore testé tout ça mais ça à l'air bien fourni :)

Bon code à tous !

- page 1 de 2