Question

Try to ignore some of the ugly if statements :D. I am very new to CSOM and caml. Is it possible to write Caml statement that returns the Folders in the Root of the document library only? Apologies if this is unclear! Happy Friday to all!

using (ClientContext clientContext = new ClientContext(webUri))
        {

            int rowLimit = 1;
            var camlQuery = new CamlQuery();
            camlQuery.ViewXml = @"<View Scope='RecursiveAll'><Query></Query><RowLimit Paged='TRUE'>" + rowLimit + "</RowLimit></View>";

            clientContext.Credentials = new SharePointOnlineCredentials(userName, password);
            ListItemCollectionPosition position = null;

            // This value is NOT List internal name
            List targetList = clientContext.Web.Lists.GetByTitle("Clients");

            //1st attempt
            //FolderCollection oFolderCollection = targetList.RootFolder.Folders;
            //clientContext.Load(oFolderCollection);
            //clientContext.ExecuteQuery();

            int clientCount = 0;
            do
            {
                ListItemCollection listItems = null;
                camlQuery.ListItemCollectionPosition = position;
                listItems = targetList.GetItems(camlQuery);
                clientContext.Load(listItems);
                clientContext.ExecuteQuery();
                position = listItems.ListItemCollectionPosition;
                items.AddRange(listItems.ToList());

                foreach (ListItem item in listItems)
                {
                    if (item != null && item.Folder != null)
                    {
                        try
                        {
                            clientContext.Load(item);
                            clientContext.Load(item.Folder);
                            clientContext.Load(item.Folder.ParentFolder);
                            clientContext.ExecuteQuery();
                            if ((item != null && item.Folder != null) && item.Folder.GetType() == typeof(Folder))
                            {
                                clientCount++;



                                //currently getting all files and folders, just want to start at top level folder then load in others if/as needed
                                Console.WriteLine(clientCount + "- Client: " + item.Folder.Name);
                                //clientFileDiver(item.Folder, clientContext);

                            }
                        }
                        catch (Microsoft.SharePoint.Client.ServerException)
                        {
                            if(item == null || item.Folder == null)
                            {
                                continue;
                            }
                            throw;
                        }
                        catch (ServerObjectNullReferenceException)
                        {
                            if (item == null || item.Folder == null)
                            {
                                continue;
                            }
                        }
                        catch (Exception)
                        {
                            throw;
                        }

                    }

                }

            }
            while (position != null);

EDIT: New Query I'm attempting but getting view threshold error again even with row limit

int rowLimit = 1;
string folderTypeId = "0x0120";
var camlQuery = new CamlQuery();
camlQuery.ViewXml = @"<View><Query><Where><BeginsWith><FieldRefName='ContentTypeId'/><Value Type = 'ContentTypeId'>" + folderTypeId + " </ Value ></BeginsWith></Where></Query><RowLimit Paged = 'TRUE'>" + rowLimit   + "</RowLimit></View>";
Was it helpful?

Solution

If you are interested to get only 'Folders', then use following in your CAML query:

<Where>
  <BeginsWith>
    <FieldRef Name="ContentTypeId" />
    <Value Type="ContentTypeId">0x0120</Value>
  </BeginsWith>
</Where>

SharePoint folder content type for folder starts with 0x0120. Check this Microsoft Document for details on content type ids.

You will need 'BeginsWith' since the actual content type id for Folders in your document library will be inherited and they will have the following format:

Parent Content Type ID + "00" + Hexadecimal GUID

Let me know if this helps.

OTHER TIPS

Try changing this line:

camlQuery.ViewXml = @"<View Scope='RecursiveAll'><Query></Query><RowLimit Paged='TRUE'>" + rowLimit + "</RowLimit></View>";

to this

camlQuery.ViewXml = @"<View><Query></Query><RowLimit Paged='TRUE'>" + rowLimit + "</RowLimit></View>";

Remove the Scope='RecursiveAll' part from it. You can read more on View Scope property here.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top