Loupe

Lister de manière récursive les bibliothèques de documents sous SharePoint - Partie 1

Dans un précédent article, Pierre vous a expliqué comment utiliser JSOM (JavaScript Object Model) pour obtenir simplement les pièces jointes d’un ou plusieurs éléments en un seul appel JSOM sous SharePoint 2013. Au travers de cet article, nous allons voir comment utiliser CSOM (Client Side Object Model) pour récupérer de manière récursive l'ensemble des éléments (fichiers/dossiers) contenus dans des bibliothèques de documents SharePoint.

 L'utilisation de CSOM est relativement simple, la chose la plus importante à savoir est que vous devez charger les données que vous voulez utiliser, sinon vous aurez une exception indiquant que la donnée n'a pas encore été initialisée. Hormis cela, le code parle de lui-même! Par exemple, on commence par récupérer le site Web principal sur lequel on se connecte:

private static void ListDocumentsWithCsom()
{
    using (ClientContext clientContext = new ClientContext("https://monclient.sharepoint.com/sites/monsite"))
    {
        clientContext.Credentials = InternalSharePointHelper.GetCredential("mysuperuser@domain.com", "mySecretPassword");

        var rootWeb = clientContext.Web;
        clientContext.Load(rootWeb, web => web.Title);
        clientContext.ExecuteQuery();

        var rootSite = new Site {Name = rootWeb.Title};

        RootSite = rootSite;

        GetWebContentWithCsom(clientContext, rootWeb, rootSite);
    }
}

Sur le site Web courant, on va ensuite appeler la méthode GetSubwebsForCurrentUser qui va nous permettre de récupérer la liste des sous-sites auxquels l'utilisateur a accès. Ensuite, on va simplement boucler sur chacun des sites récupérés pour vérifier si ceux-ci contiennent d'autres sous-sites accessibles:

private static void GetWebContentWithCsom(ClientContext clientContext, Web website, Site parent)
{
    var subWebsites = website.GetSubwebsForCurrentUser(null);
    clientContext.Load(subWebsites);
    clientContext.ExecuteQuery();

    if (subWebsites.Count > 0)
    {
        foreach (var subWebsite in subWebsites)
        {
            var subSite = new Site { Name = subWebsite.Title };
            parent.Children.Add(subSite);

            GetWebContentWithCsom(clientContext, subWebsite, subSite);
        }
    }

    // Reste du code
}

Dans le cas contraire, on va récupérer la liste des listes du site courant:

var websiteLists = clientContext.LoadQuery(website.Lists.Where(list => list.BaseType == BaseType.DocumentLibrary && list.BaseTemplate == 101));
clientContext.ExecuteQuery();
            
foreach (var list in websiteLists)
{
    clientContext.Load(list, i => i.RootFolder, i => i.IsSiteAssetsLibrary, i => i.IsCatalog, i => i.IsPrivate, i => i.IsApplicationList, i => i.IsSystemList);
}

clientContext.ExecuteQuery();

bool ListFilter(List list) => !list.Hidden 
    && !list.IsSiteAssetsLibrary 
    && !list.IsCatalog 
    && !list.IsPrivate 
    && !list.IsApplicationList
    && !list.IsSystemList
    && list.Title != "Form Templates"
    && list.Title != "Customized Reports"
    && list.Title != "Site Collection Documents"
    && list.Title != "Site Collection Images"
    && list.Title != "Images";
            
foreach (var list in websiteLists.Where(ListFilter))
{
    var serverRelativeUrl = list.RootFolder.ServerRelativeUrl;
    var absoluteUrl = new Uri(clientContext.Url).GetLeftPart(UriPartial.Authority) + serverRelativeUrl;

    var folder = new Folder { Name = list.Title, Url = absoluteUrl };

    GetFoldersWithCsom(clientContext, list.RootFolder.Folders, folder);

    parent.Folders.Add(folder);
}

Et, pour chaque liste, on va récupérer la liste des répertoires qui la compose ce qui, par code, se traduit comme ceci:

public static void GetFoldersWithCsom(ClientContext clientContext, FolderCollection folderCollection, Folder parentFolder)
{
    clientContext.Load(folderCollection);
    clientContext.ExecuteQuery();

    foreach (var folder in folderCollection.Where(f => f.Name != "Forms"))
    {
        var serverRelativeUrl = folder.ServerRelativeUrl;
        var absoluteUrl = new Uri(clientContext.Url).GetLeftPart(UriPartial.Authority) + serverRelativeUrl;

        var subFolder = new Folder {  Name = folder.Name, Url = absoluteUrl };
        parentFolder.Folders.Add(subFolder);

        GetFoldersWithCsom(clientContext, folder.Folders, subFolder);
    }
}

Et voilà ! Grâce au CSOM et à un peu de récursivité, nous sommes en mesure de récupérer l'ensemble des dossiers des bibliothèques SharePoint ! Cela fonctionne bien sûr avec les fichiers, libre à vous d'adapter le code si besoin.

Il est à noter que, même si cela fonctionne, il s'agit d'une opération extrêmement coûteuse en termes de temps car, plus vous disposez de bibliothèques remplies, plus il sera nécessaire de faire des appels réseau pour en récupérer le contenu. Dans le cas de la mise en place d'un explorateur de documents SharePoint, il peut être intéressant de préférer effectuer les appels réseaux à chaque fois que l'utilisateur essaye de déplier un noeud, afin d'optimiser les performances.

Dans la 2ème partie, nous verrons comment faire la même chose en utilisant l'API REST de SharePoint, afin de voir ce que cela change et si cela a un impact sur les délais!

Happy coding !

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus