11

I'm trying to create nested folders in my document library so it looks like this:

http://site/PublicDocuments/Folder1/Folder2/Folder3/

The document library "Public Documents" exists but none of the folders exist yet.

Here's the working code for those interested:

    ClientContext clientContext = new ClientContext(url);
    Web web = clientContext.Web;
    var query = clientContext.LoadQuery(web.Lists.Where(p => p.Title == "Public Documents"));
    clientContext.ExecuteQuery();
    List list = query.FirstOrDefault();
    var folder = list.RootFolder;

    clientContext.Load(folder);
    clientContext.ExecuteQuery();

    string[] namesArray = new string[] { "/Folder1", "Folder2", "Folder3" };
    foreach(string name in namesArray)
    {
        folder = folder.Folders.Add(name);            
    }

    clientContext.ExecuteQuery();

Thanks!

8

Try not calling clientContext.Load, for example this works for me:

var folder = list.RootFolder;
clientContext.Load(folder);
clientContext.ExecuteQuery();
folder = folder.Folders.Add("Folder 1");
folder.Folders.Add("Folder 2");
clientContext.ExecuteQuery();
  • Thanks, that works. I'm going to post the code using the foreach loop shortly – ATAI Nov 15 '12 at 22:58
9

How to create Folder (including nested) via CSOM in SharePoint

/// <summary>
/// Create Folder (including nested) client object
/// </summary>
/// <param name="web"></param>
/// <param name="listTitle"></param>
/// <param name="fullFolderPath"></param>
/// <returns></returns>
public static Folder CreateFolder(Web web, string listTitle, string fullFolderPath)
{
    if (string.IsNullOrEmpty(fullFolderPath))
        throw new ArgumentNullException("fullFolderPath");
    var list = web.Lists.GetByTitle(listTitle);
    return CreateFolderInternal(web, list.RootFolder, fullFolderPath);
}


private static Folder CreateFolderInternal(Web web, Folder parentFolder, string fullFolderPath)
{
    var folderUrls = fullFolderPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
    string folderUrl = folderUrls[0];
    var curFolder = parentFolder.Folders.Add(folderUrl);
    web.Context.Load(curFolder);
    web.Context.ExecuteQuery();

    if (folderUrls.Length > 1)
    {
        var folderPath = string.Join("/", folderUrls, 1, folderUrls.Length - 1);
        return CreateFolderInternal(web, curFolder, folderPath);
    }
    return curFolder;
}

Usage

 using (var ctx = new ClientContext("https://contoso.intranet.com/"))
 {
       var folder = CreateFolder(ctx.Web, "Shared Documents", "FolderA/SubFolderA/SubSubFolderA");
 }
  • Thank you for this answer. I was wondering if you could check if one or more folder in the nested path already exists and if so skip that. – Animesh Jan 30 '18 at 10:03
6

How about something like this:

 public static Folder EnsureFolder(ClientContext ctx, Folder ParentFolder, string FolderPath)
    {
        //Split up the incoming path so we have the first element as the a new sub-folder name 
        //and add it to ParentFolder folders collection
        string[] PathElements = FolderPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);           
        string Head = PathElements[0];
        Folder NewFolder = ParentFolder.Folders.Add(Head);
        ctx.Load(NewFolder);
        ctx.ExecuteQuery();

        //If we have subfolders to create then the length of PathElements will be greater than 1
        if (PathElements.Length > 1)
        {
            //If we have more nested folders to create then reassemble the folder path using what we have left i.e. the tail
            string Tail = string.Empty;
            for (int i = 1; i < PathElements.Length; i++)
                Tail = Tail + "/" + PathElements[i];

            //Then make a recursive call to create the next subfolder
            return EnsureFolder(ctx, NewFolder, Tail);
        }
        else
            //This ensures that the folder at the end of the chain gets returned
            return NewFolder;            
    }

and then you can call it with following:

ctx.Load(TargetList.RootFolder);
ctx.ExecuteQuery();
Folder NewFolder = EnsureFolder(ctx, TargetList.RootFolder, "/Folder1/Folder2/Folder3");
1

var list = ctx.GetListByTitle("MyList); list.EnableFolderCreation = true; list.RootFolder.EnsureFolder("NewFolder1").EnsureFolder("NewSubFolderToFolder1"); ctx.ExecuteQuery();

0

Try looping through and adding each folder and then call ExecuteQuery

      string[] namesArray = new string[] {  "Folder1","Folder2"};
      foreach (string name in namesArray)
       {
        //Add Folder
        var folders = list.RootFolder.Folders;
        clientContext.Load(folders);
        clientContext.ExecuteQuery();
        var newFolder = folders.Add(name);
      }
      //Execute request
      clientContext.ExecuteQuery();
0

Use the below simple code.

 public void CreateFolder(string url, string foldername,string documentlibname)
    {
        try
        {
            ClientContext clientContext = new ClientContext(url);
            Web web = clientContext.Web;
            var query = clientContext.LoadQuery(web.Lists.Where(p => p.Title == documentlibname));## Heading ##
            clientContext.ExecuteQuery();
            List list = query.FirstOrDefault();
            var folder = list.RootFolder;
            clientContext.Load(folder);
            clientContext.ExecuteQuery();
            string[] PathElements = foldername.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < PathElements.Length; i++)
            {
                folder = folder.Folders.Add(PathElements[i].ToString());
                clientContext.ExecuteQuery();
            }



            //folder = folder.Folders.Add(foldername);
            //clientContext.ExecuteQuery();
        }
        catch (System.Exception ex)
        {

            throw;
        }
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.