I am using the client side object model approach C# in order to retrieve all list items from a document library containing sub folders. I checked out the MSDN documentation and I am stuck as to why I cannot get the field property, or if I am even doing this right.
NetworkCredential credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
ClientContext clientcontext = new ClientContext(Resources.defaultSPSite);
clientcontext.Credentials = credentials;
//Load Libraries from SharePoint
//Web site = clientcontext.Web;
clientcontext.Load(clientcontext.Web.Lists);
clientcontext.ExecuteQuery();
//List sharedDocumentsList = clientcontext.Web.Lists.GetByTitle("TestLDOCS");
//CamlQuery camlQuery = new CamlQuery();
//camlQuery.ViewXml = @"<View Scope='Recursive'><Query></Query></View>";
foreach (List list in clientcontext.Web.Lists)
{
clientcontext.Load(list);
clientcontext.ExecuteQuery();
//list.TemplateFeatureId.ToString().Equals("") &&
string baseType = list.BaseType.ToString();
string listTitle = list.Title.ToString();
if (list.BaseType.ToString().Equals("DocumentLibrary", StringComparison.InvariantCultureIgnoreCase) && list.Title.ToString().Equals("TestLDOCS", StringComparison.InvariantCultureIgnoreCase))
{
foreach (Folder subFolder in list.RootFolder.Folders)
{
foreach (File f in subFolder.Files)
{
Console.WriteLine((string) f.Title);
}
}
}
}
}
The error that I am receiving is that the "foreach(File f in subFolder.Files)" collection may not be initialized error. Is there anyway to get the field values of all documents in every subfolder within a document library using CSOM?
I know you can strongly type the field values as well with a list item ie (listItem["fieldName"]). Should I go this route instead?
foreach (List list in clientcontext.Web.Lists)
{
clientcontext.Load(list);
clientcontext.ExecuteQuery();
//list.TemplateFeatureId.ToString().Equals("") &&
string baseType = list.BaseType.ToString();
string listTitle = list.Title.ToString();
if (list.BaseType.ToString().Equals("DocumentLibrary", StringComparison.InvariantCultureIgnoreCase) && list.Title.ToString().Equals("TestLDOCS", StringComparison.InvariantCultureIgnoreCase))
{
foreach (Folder subFolder in list.RootFolder.Folders)
{
clientcontext.Load(subFolder.Files);
clientcontext.ExecuteQuery();
foreach (File f in subFolder.Files)
{
Console.WriteLine((string) f.Title);
}
}
}
}
}
Some recommendations:
1) Prefer ClientRuntimeContext.LoadQuery method to load a specific lists, for example:
var lists = ctx.LoadQuery(ctx.Web.Lists.Where(l => l.BaseType == BaseType.DocumentLibrary));
ctx.ExecuteQuery();
2) Since SharePoint SCOM supports Request Batching it is recommended to minimize the number of requests to the server. The following example demonstrates how to perform a single request to the server in order to load all files from document libraries:
foreach (var list in lists)
{
var items = list.GetItems(CreateAllFilesQuery());
ctx.Load(items, icol => icol.Include(i => i.File));
results[list.Title] = items.Select( i=>i.File);
}
ctx.ExecuteQuery();
3) Prefer to load all files via CAML query as demonstrated below:
public static CamlQuery CreateAllFilesQuery()
{
var qry = new CamlQuery();
qry.ViewXml ="<View Scope=\"RecursiveAll\"><Query><Where><Eq><FieldRef Name=\"FSObjType\" /><Value Type=\"Integer\">0</Value></Eq></Where></Query></View>";
return qry;
}
Then the following example will return all the files in library:
var items = list.GetItems(CreateAllFilesQuery());
ctx.Load(items, icol => icol.Include(i => i.File));
ctx.ExecuteQuery();
var files = items.Select( i=>i.File).ToList();
It is more optimized way of loading specific lists from performance perspective
Complete example
How to load all files from document libraries using SharePoint CSOM:
using (var ctx = new ClientContext(webUri))
{
var results = new Dictionary<string, IEnumerable<File>>();
var lists = ctx.LoadQuery(ctx.Web.Lists.Where(l => l.BaseType == BaseType.DocumentLibrary));
ctx.ExecuteQuery();
foreach (var list in lists)
{
var items = list.GetItems(CreateAllFilesQuery());
ctx.Load(items, icol => icol.Include(i => i.File));
results[list.Title] = items.Select( i=>i.File);
}
ctx.ExecuteQuery();
//Print results
foreach (var result in results)
{
Console.WriteLine("List: {0}",result.Key);
foreach (var file in result.Value)
{
Console.WriteLine("File: {0}", file.Name);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With