Reputation: 1796
I am attempting to pull back all the Folders and SubFolders (there can be any number) from a SharePoint site. I don't want the files (there could be thousands), so I am basically trying to just build a folder hierarchy. Additionally I only want the User created folders and the main "Documents" folders, not all the system ones.
That said, I found the following example that I though should have worked, but when I reduce it to just the folders I only get the top level folders:
https://stackoverflow.com/questions/16652288/sharepoint-client-get-all-folders-recursively
Here is the state of the current code. I am probably just missing something on the load (like an expresssion?):
public static void LoadContent(Microsoft.SharePoint.Client.Web web, out Dictionary<string, IEnumerable<Microsoft.SharePoint.Client.Folder>> listsFolders)
{
listsFolders = new Dictionary<string, IEnumerable<Microsoft.SharePoint.Client.Folder>>();
var listsItems = new Dictionary<string, IEnumerable<Microsoft.SharePoint.Client.ListItem>>();
var ctx = web.Context;
var lists = ctx.LoadQuery(web.Lists.Where(l => l.BaseType == Microsoft.SharePoint.Client.BaseType.DocumentLibrary));
ctx.ExecuteQuery();
foreach (var list in lists)
{
var items = list.GetItems(Microsoft.SharePoint.Client.CamlQuery.CreateAllFoldersQuery());
ctx.Load(items);
listsItems[list.Title] = items;
}
ctx.ExecuteQuery();
foreach (var listItems in listsItems)
{
listsFolders[listItems.Key] = listItems.Value.Where(i => i.FileSystemObjectType == Microsoft.SharePoint.Client.FileSystemObjectType.Folder).Select(i => i.Folder);
}
}
UPDATE
Just to help out anyone else who might just want the main folders and subfolders as a list of urls, here is the final code. I suspect it could be simplified but it is working. The trick after the help below was to get the "root" folder paths, which required a separate query. I think that is where it could prove easier to just get Folders -> Subfolders, but I have Folders -> Subfolders -> Subfolders and this solution gets that last subfolder, along with the root folders.
public static void LoadContent(Microsoft.SharePoint.Client.Web web, List<String> foldersList)
{
Dictionary<string, IEnumerable<Folder>> listsFolders = new Dictionary<string, IEnumerable<Folder>>();
var listsItems = new Dictionary<string, IEnumerable<ListItem>>();
var ctx = web.Context;
var lists = ctx.LoadQuery(web.Lists.Include(l => l.Title).Where(l => l.BaseType == BaseType.DocumentLibrary && !l.Hidden && !l.IsCatalog && !l.IsSiteAssetsLibrary));
ctx.ExecuteQuery();
foreach (var list in lists)
{
ctx.Load(list.RootFolder);
ctx.ExecuteQuery();
}
foreach (var list in lists)
{
if (list.Title != "Form Templates" && list.Title != "MicroFeed" && list.Title != "Site Assets" && list.Title != "Site Pages")
{
foldersList.Add(list.RootFolder.ServerRelativeUrl);
var items = list.GetItems(CamlQuery.CreateAllFoldersQuery());
ctx.Load(items, icol => icol.Include(i => i.FileSystemObjectType, i => i.Folder));
listsItems[list.Title] = items;
}
}
ctx.ExecuteQuery();
foreach (var listItems in listsItems)
{
listsFolders[listItems.Key] = listItems.Value.Where(i => i.FileSystemObjectType == FileSystemObjectType.Folder).Select(i => i.Folder);
}
foreach (var item in listsFolders)
{
IEnumerable<Folder> folders = item.Value;
foreach (Folder folder in folders)
{
foldersList.Add(folder.ServerRelativeUrl);
}
}
}
An example of what this returns:
Upvotes: 1
Views: 747
Reputation: 59358
1) In the provided example, to return Folder
object, it needs to be explicitly included otherwise the exception occur, so replace the line:
ctx.Load(items);
with:
ctx.Load(items, icol => icol.Include(i => i.FileSystemObjectType, i => i.Folder));
2) "system" libraries could be excluded like this:
var lists = ctx.LoadQuery(web.Lists.Where(l => !l.Hidden && !l.IsCatalog && !l.IsSiteAssetsLibrary));
Modified example
public static void LoadContent(Web web, out Dictionary<string, IEnumerable<Folder>> listsFolders)
{
listsFolders = new Dictionary<string, IEnumerable<Folder>>();
var listsItems = new Dictionary<string, IEnumerable<ListItem>>();
var ctx = web.Context;
var lists = ctx.LoadQuery(web.Lists.Include(l =>l.Title).Where(l => l.BaseType == BaseType.DocumentLibrary && !l.Hidden && !l.IsCatalog && !l.IsSiteAssetsLibrary));
ctx.ExecuteQuery();
foreach (var list in lists)
{
var items = list.GetItems(CamlQuery.CreateAllFoldersQuery());
ctx.Load(items, icol => icol.Include(i => i.FileSystemObjectType, i => i.Folder));
listsItems[list.Title] = items;
}
ctx.ExecuteQuery();
foreach (var listItems in listsItems)
{
listsFolders[listItems.Key] = listItems.Value.Where(i => i.FileSystemObjectType == FileSystemObjectType.Folder).Select(i => i.Folder);
}
}
Upvotes: 1
Reputation: 5493
Try this.
var lists = ctx.LoadQuery(ctx.Web.Lists.Where(l => l.BaseType == BaseType.DocumentLibrary));
ctx.ExecuteQuery();
foreach (var list in lists)
{
Console.WriteLine(list.Title);
ListItemCollection listitems = list.GetItems(CamlQuery.CreateAllFoldersQuery());
ctx.Load(listitems, items => items.Include(item => item.Id,item=>item.Folder));
ctx.ExecuteQuery();
foreach (var item in listitems)
{
Console.WriteLine(item.Folder.ServerRelativeUrl);
}
}
Upvotes: 0