5
votes

I want to create folder on SharePoint document library using client object model (C#). Below is the code which does that.

 ContentTypeCollection listContentTypes = list.ContentTypes;
 clientContext.Load(listContentTypes, types => types.Include
                                     (type => type.Id, type => type.Name,
                                     type => type.Parent));

 var result = clientContext.LoadQuery(listContentTypes.Where(c => c.Name == "Folder"));

clientContext.ExecuteQuery();

ContentType folderContentType = result.FirstOrDefault();

ListItemCreationInformation newItemInfo = new ListItemCreationInformation();
newItemInfo.UnderlyingObjectType = FileSystemObjectType.Folder;
newItemInfo.LeafName = Foldername;
ListItem newListItem = list.AddItem(newItemInfo);

newListItem["ContentTypeId"] = folderContentType.Id.ToString();
newListItem["Title"] = Foldername;
ewListItem.Update();

clientContext.Load(list);
clientContext.ExecuteQuery();

Now i have thousands of folders to be created on library. So is there any other way i can do this using Bulk operation, so client to server connection will only be called once.

Problem is it is taking too much time to create folder because for each and every folder it will call SharePoint object.

2

2 Answers

10
votes

It's easy. Just add all of the folders you wish to create to a list and then loop through the list and create all the list items before running the ExecuteQuery function:

        List<string> folderNames = new List<string>();
        folderNames.Add("Folder 1");
        folderNames.Add("Folder 2");
        folderNames.Add("Folder 3");

        ClientContext context = new ClientContext("https://sharepoint.Site/Test");
        List list = context.Web.Lists.GetByTitle("Documents");
        var folder = list.RootFolder;
        context.Load(folder);
        context.ExecuteQuery();

        foreach (string folderName in folderNames)
        {
            ListItemCreationInformation newItemInfo = new ListItemCreationInformation();
            newItemInfo.UnderlyingObjectType = FileSystemObjectType.Folder;
            newItemInfo.LeafName = folderName;
            ListItem newListItem = list.AddItem(newItemInfo);
            newListItem["Title"] = folderName;
            newListItem.Update();
        }
        context.ExecuteQuery();

Works like a charm. You just need to stage all of your folder paths/names before you run any CSOM code.

9
votes

Some recommendations based on your example:

  • Since content type property is not required, the first request for getting Folder content type could be omitted.
  • in this example there is no need to load list content types and list objects.

Having said that, below is provided the modified example for creating a folder:

public static class ListExtensions
{
    public static void CreateFolder(this List list, string name)
    {
        var info = new ListItemCreationInformation
        {
            UnderlyingObjectType = FileSystemObjectType.Folder,
            LeafName = name
        };
        var newItem = list.AddItem(info);
        newItem["Title"] = name;
        newItem.Update();
    }
}

Usage

using (var ctx = new ClientContext(webUri))
{
    var list = ctx.Web.Lists.GetByTitle(listTitle);
    list.CreateFolder(folderName);
    ctx.ExecuteQuery();
}

Regarding bulk operation, since SharePoint CSOM supports Request Batching, multiple folders could be created as demonstrated below:

using (var ctx = new ClientContext(webUri))
{
    var list = ctx.Web.Lists.GetByTitle(listTitle);
    for (var year = 2000; year <= 2015; year++)
    {
       list.CreateFolder(year.ToString());
    }
    ctx.ExecuteQuery();
}

In that case only a single request will be submitted to the server.