Loupe

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

Dans mon précédent article, j'expliquais comment utiliser CSOM pour lister les bibliothèques de documents SharePoint. Cette fois, nous allons voir comment faire la même chose en utilisant l'API REST et ainsi juger des différences !

La logique est la même que précédemment: on commence par se connecter au site principal (je mets de côté le code permettant de gérer l'authentification à SharePoint, il ne s'agit que d'utiliser un CookieContainer lors des appels effectués à l'API):

private static void ListDocumentsWithRest()
{
    var rootUrl = "https://monclient.sharepoint.com/sites/monsite/";

    using (var spClient = new SPHttpClient(new Uri(rootUrl), "mysuperuser@domain.com", "mySecretPassword"))
    {
        var getWebEndpointUrl = $"{rootUrl}/_api/web";
        var getWebResults = spClient.ExecuteJson(getWebEndpointUrl);

        var rootSite = new Site { Name = getWebResults["d"].Value<string>("Title") };

        RootSite = rootSite;

        GetWebContentWithRest(spClient, getWebResults["d"].Value<string>("Url"), rootSite);
    }
}

On constate que, même si le code est sensiblement similaire à la version CSOM, la récupération des valeurs depuis l'API (qui utilise ODATA) est tout de même un peu plus "complexe".

La méthode pour récupérer les sites auxquels l'utilisateur a accès est, là encore, assez ressemblante à la différence que nous allons cette fois utiliser la méthode GetSubwebsFilteredForCurrentUser de l'API:

var getSubwebsForCurrentUserEndpointUrl = $"{siteUrl}/_api/web/GetSubwebsFilteredForCurrentUser(nwebtemplatefilter=-1,nconfigurationfilter=-1)";
var getSubwebsForCurrentUserResults = spClient.ExecuteJson(getSubwebsForCurrentUserEndpointUrl);

var subWebsites = getSubwebsForCurrentUserResults["d"]["results"] as JArray;
if (subWebsites != null && subWebsites.Count > 0)
{
    foreach (var subWebsite in subWebsites)
    {
        var subSite = new Site { Name = subWebsite.Value<string>("Title") };
        parent.Children.Add(subSite);

        var serverRelativeUrl = subWebsite.Value<string>("ServerRelativeUrl");
        var absoluteUrl = new Uri(siteUrl).GetLeftPart(UriPartial.Authority) + serverRelativeUrl;

        GetWebContentWithRest(spClient, absoluteUrl, subSite);
    }
}

La récupération des listes du site passe par un appel à l'API en lui spécifiant les filtres que l'on veut appliquer. Ayant fait le choix de ne pas utiliser des outils / librairies telles que celles proposées par PnP (Patterns And Practices), le code est plus verbeux que compliqué:

var getListsEndpointUrl = $"{siteUrl}/_api/web/lists?$filter=(BaseTemplate eq 101) and (BaseType eq 1) and (Hidden eq false) and (IsSiteAssetsLibrary eq false) and (IsCatalog eq false) and (IsPrivate eq false) and (IsApplicationList eq false) and (IsSystemList eq false) and (Title ne 'Form Templates') and (Title ne 'Customized Reports') and (Title ne 'Site Collection Documents') and (Title ne 'Site Collection Images') and (Title ne 'Images')&$expand=RootFolder";

var getListsResults = spClient.ExecuteJson(getListsEndpointUrl);

var lists = getListsResults["d"]["results"] as JArray;
if (lists != null && lists.Count > 0)
{
    foreach (var list in lists)
    {
        var serverRelativeUrl = list.Value<JToken>("RootFolder").Value<string>("ServerRelativeUrl");
        var absoluteUrl = new Uri(siteUrl).GetLeftPart(UriPartial.Authority) + serverRelativeUrl;

        var folder = new Folder { Name = list.Value<string>("Title"), Url = absoluteUrl };
        GetFoldersWithRest(spClient, siteUrl, serverRelativeUrl, folder);

        parent.Folders.Add(folder);
    }
}

Enfin, la récupération des dossiers à l'intérieur d'une liste se fait via une simple méthode, appelant elle aussi l'API:

private static void GetFoldersWithRest(SPHttpClient spClient, string siteUrl, string folderServerRelativeUrl, Folder parentFolder)
{
    try
    {
        var getFoldersEndpointUrl = $"{siteUrl}/_api/web/GetFolderByServerRelativeUrl('{folderServerRelativeUrl}')/folders?$filter=(Name ne 'Forms')";
        var getFoldersResults = spClient.ExecuteJson(getFoldersEndpointUrl);

        var folders = getFoldersResults["d"]["results"] as JArray;
        if (folders != null && folders.Any())
        {
            foreach (var folder in folders)
            {
                var serverRelativeUrl = folder.Value<string>("ServerRelativeUrl");
                var absoluteUrl = new Uri(siteUrl).GetLeftPart(UriPartial.Authority) + serverRelativeUrl;

                var subFolder = new Folder { Name = folder.Value<string>("Name"), Url = absoluteUrl };
                parentFolder.Folders.Add(subFolder);

                GetFoldersWithRest(spClient, siteUrl, serverRelativeUrl, subFolder);
            }
        }
    }
    catch (Exception e)
    {
    }
}

Et voilà, nous disposons à présent de la version REST de notre méthode de listing récursif des bibliothèques de documents SharePoint !

On peut cependant se demander quelle méthode est la mieux/plus simple/plus optimisée et voici le résultat de mes tests pour le parcours d'un site contenant environ 600 éléments (fichiers et dossiers confondus):

 results.png

Bien sûr, je ne suis pas expert SharePoint, il est donc fort probable que l'un ou l'autre de mes codes (ou les 2) nécessite(nt) d'être optimisé(s) mais cela donne un aperçu et semble confirmer ce que mes collègues ont eu l'occasion de me dire: la version REST est plus rapide que la version CSOM !

Happy coding!

 

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus