Tuesday, May 29, 2007

Sharepoint 2007: upload d'un document avec ses meta-data

J'ai dû récemment faire l'application suivante: Des documents étaient générés automatiquement par une application externe. Le but du programme était de récupérer ces documents pour les mettre dans une document list, avec leurs meta-data. Puis de lancer un workflow pour approbation avec différents paramètres. Dans cet article, je vais m'attacher à l'importation des fichiers dans la liste. Je ferai un autre article pour le workflow. Le premier réflexe est bien entendu de télécharger le document dans la liste puis de faire une correspondance entre les colonnes de la liste et des meta-data. Mais étant donné que je gère les versions dans cette liste, cette façon de faire risque d'incrémenter un numéro de version pour rien, suite à deux updates (un pour le document, un pour les meta-données) Mais en cherchant un peu, j'ai trouvé un overload bien pratique... La première chose est de considérer la liste comme un folder, et de récupérer dans ce folder la collection des fichiers existants. Le folder se récupère en utilisant le nom interne de la liste. Je spécifie bien le nom interne, c'est à dire le nom qui a été utilisé la première fois lors de la création de la liste (si elle a été créée via l'UI). On trouve ce nom en regardant dans l'url de la liste. Par exemple : http://dcmoss:50010/testgy/PurchaseOrder PurchaseOder est bien le nom du folder, même si la liste s'appelle "Purchase Order". SPFolder folder = _web.GetFolder("nom interne de la liste"); SPFileCollection files = folder.Files; Puis je récupère le fichier lui-même, en le stockant dans un stream mémoire FileStream fStream = File.OpenRead("fileName"); Pour terminer je crée l'URL du fichier, avec son nom: string url = "url Site web" + "nom interne de la liste" + "/" + Path.GetFileName("fileName"); Maintenant, les meta-data doivent être stockée dans une HashTable: HashTable MetaDataTable = new HashTable(); MetaDataTable.Add("nom de colonne", "valeur"); En réalité j'ai une classe qui parse le fichier texte et qui me renvoit une hashtable. Enfin, je l'ajoute le tout à la collection de fichier de la liste: SPFile currentFile = files.Add(url, fStream, MetaDataTable, true); Le flag True permet d'écraser un fichier s'il est déjà présent. En une ligne, on ajoute un fichier avec ses meta-données. Pas mal, non ? Voici un exemple de code pour uploader un document avec les meta-données: //Using required, especially System.IO; using System.Collections.Generic; using System.Collections; using System.Text; using Microsoft.SharePoint; using System.IO; namespace DocImport { public class DocManagement { //Some variables private string _DestUrlPath = string.Empty; private string _DestFolder = string.Empty; private SPSite _site = null; private SPWeb _web = null; public DocManagment(string DestUrl, string DestFolder) { _DestUrlPath = DestUrl; _DestFolder = DestFolder; _site = new SPSite(_DestUrlPath); _web = _site.OpenWeb(); } private bool _uploadDocument(string pdfFile, string txtFile) { try { //This is mandatory for avoiding an error _web.AllowUnsafeUpdates = true; //Use the list as a folder SPFolder folder = _web.GetFolder(_DestFolder); SPFileCollection files = folder.Files; //Get the file FileStream fStream = File.OpenRead(pdfFile); HashTable MetaDataTable = new HashTable(); MetaDataTable.Add("nom de colonne", "valeur"); //Set the destination url for SharePoint string url = _DestUrlPath + _DestFolder + "/" + Path.GetFileName(pdfFile); //Add document to the list with metadata, and overwrite an existing document with the same name SPFile currentFile = files.Add(url, fStream, MetaDataTable, true); fStream.Close(); return true; } catch (Exception x) { throw new Exception(x.Message); } } }

Wednesday, May 23, 2007

Sharepoint 2007 Workflow Update Item

Dans un workflow déclenché par une modification de l'item d'une liste, il est souvent nécessaire de mettre à jour une meta-donnée de cet item. Le principe est simple en utilisant par exemple : workflowProperties.Item["Status"] = "Archived"; Mais que ce passe-t-il lorsqu'on met à jour ? Le fait de faire workflowProperties.Item.update(); déclenche l'événement de mise à jour, et donc redéclenche le workflow, donc une erreur car une instance du même workflow est déjà active sur cet item. La réponse est dans l'instruction suivante : workflowProperties.Item.SystemUpdate(); Cette méthode permet d'écrire directement dans la base, sans déclencher les événements sur l'item. D'autre part, il est possible de spécifier un flag (true/false) pour incrémenter ou non la version.