Bonjour à tous,

Ceux qui l'ont déjà expérimenté le savent bien, il y a des choses que le modèle objet client de SharePoint 2010 sait faire à merveille et d'autres qui semblent avoir complètement été oubliées, y compris les plus basiques....

Comme vous l'aurez compris au titre de ce post, l'une d'elles est la possibilité d'ajouter une pièce jointe à un élément de liste. Il semble que Microsoft n'est pas envisagé ce cas, ou que pour des raisons obscures ils ne l'aient pas implémenté.

Qu'à cela ne tienne, voici deux méthodes pour les ajouter, une n'est utilisable que si vous avez déjà au moins une pièce jointe attachée à votre élément, l'autre est utilisable tout le temps mais fait référence aux WebServices de SharePoint...


Première méthode :

Cette méthode ne fonctionne que si le répertoire contenant les pièces jointes de l'élément existe déjà, sinon vous recevrez une erreur "409 : Erreur de conflit"

Vous remarquerez au passage que Microsoft n'a toujours pas amélioré son système de message d'erreur. D'un point de vue développeur il ne s'agit pas d'un conflit mais de l'absence du répertoire pour stocker la pièce jointe.

Le seul moyen que ce répertoire existe est que vous ayez ajouté une ou plusieurs pièces jointes à votre élément, soit par l'interface utilisateur, soit par le deuxième méthode ci-dessous.

Ne cherchez pas à créer ce répertoire, j'ai testé toutes les méthodes que j'ai pu trouvé sur Internet et aucune ne fonctionne pour créer un sous-répertoire dans le répertoire "Attachments" de la liste. Il semble que ce soit un comportement confirmé par Microsoft...


string uploadLocation = string.Format("{0}/Lists/{1}/Attachments/{2}/{3}", webName, listName, itemId, Path.GetFileName(fileName));
Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, uploadLocation, fileStream, true);


Dans ce code :

  • webName est le nom (url) du site Web,
  • listName est le nom (url) de la liste,
  • itemId est l'Id (int) de l"élément sur lequel ajouter la pièce jointe,
  • filename est le nom de la pièce jointe,
  • clientContext représente le context client pour le site web contenant la liste,
  • enfin fileStream correspond au contenu du fichier représenté sous forme de stream.

Deuxième méthode :

Cette méthode fonctionne à tous les coups mais nécessite de faire une référence web au webservice de liste de SharePoint.


ListsWebService.Lists listsWS = new ListsWebService.Lists();
listsWS.UseDefaultCredentials = true;
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer,0,(int)fileStream.Length);
fileStream.Close();
listsWS.AddAttachment(listName, itemId.ToString(), fileName, buffer);

Dans ce code :

  • ListsWebService et le nom de la classe proxy vers le webservice de listes de SharePoint (http://urldevotresite/_vti_bin/lists.asmx),
  • fileStream représente le contenu de la pièce jointe sous forme de Stream,
  • listName est le nom de la liste,
  • enfin itemId correspond à l'ID (int) du listitem auquel ajouter la pièce jointe.

Bonus :

Aller parce que je suis sympa (les fleurs sont pas chers en ce moment), je vous donne la méthode complète pour ajouter l'élément de liste et la première pièce jointe. La petite difficulté vient du fait que lors de l'ajout de l'élément à la liste, l'ID de celui n'est pas connu et qu'il est nécessaire de le recharger ensuite pour le connaître.


using (ClientContext clientContext = new ClientContext(siteUrl))
{
   var list = clientContext.Web.Lists.GetByTitle(listName);
   clientContext.Load(list);
   ListItemCreationInformation itemInformation = null;
   ListItem listItem = list.AddItem(itemInformation);
   listItem["Nom"] = Nom;
   listItem["Prenom"] = Prenom;
   listItem["email"] = Email;
   listItem.Update();
   clientContext.ExecuteQuery();
   CamlQuery query = new CamlQuery();
   query.ViewXml = @"
         <Query>
            <Where>
               <And>
                  <And>
                     <Eq>
                        <FieldRef name="Nom" />
                        <Value type="Text">" + Nom + @"</Value>
                     </Eq>
                     <Eq>
                        <FieldRef name="Prenom" />
                        <Value type="Text">" + Prenom + @"</Value>
                     </Eq>
                  </And>
                  <Eq>
                     <FieldRef name="email" />
                     <Value type="Text">" + Email+ @"</Value>
                  </Eq>
               </And>
            </Where>
         </Query>
      </View>";
   var refreshedItem = list.GetItems(query);
   clientContext.Load(refreshedItem);
   clientContext.ExecuteQuery();
   if (refreshedItem.Count != 1)
   {
      // TODO Manage Error
   }
   if (!string.IsNullOrEmpty(fileName) && fileStream.Length > 0)
      {
         ListsWebService.Lists listsWS = new ListsWebService.Lists();
         listsWS.UseDefaultCredentials = true;
         byte[] buffer = new byte[fileStream.Length];
         fileStream.Read(buf,0,(int)fileStream.Length);
         fileStream.Close();
         listsWS.AddAttachment(listName, refreshedItem[0].Id.ToString(), fileName, buffer);
      }
}


Bon code à tous ! Edgar