0

I have the following CSOM inside my remote event receiver for SharePoint online site:-

ListItemCreationInformation listItemCreationInformation = new ListItemCreationInformation();
listItemCreationInformation.UnderlyingObjectType = FileSystemObjectType.Folder;
listItemCreationInformation.LeafName = *********************
List templatelsit = context.Web.GetList(webrelativeurl + "/" + template["TemplateListUrl"]);
ListItem listItem2 = templatelsit.AddItem(listItemCreationInformation);

but on some folders such as when my listItemCreationInformation = /123456 International Holdings 1234567 (in Liquidation)/Investment/Portfolio Management/Strategy/Asset management initial strategy i am getting this error:-

System.ArgumentException: 'The 'parameters.LeafName' argument is invalid.'

is this because of the length of the folder path? if so, then what is the maximum length i can have? keeping in mind if i try to add the path using the UI i can add this folder /123456 International Holdings 1234567 (in Liquidation)/Investment/Portfolio Management/Strategy/Asset management initial strategy and even more sub-folders...

2
  • What is the object listItemCreationInformation2? You don't show the initialization of that object in your code. – Trevor Seward May 3 '20 at 15:47
  • 1
    @TrevorSeward sorry i updated my code – John John May 3 '20 at 15:49
0

Looks like you are trying to create nested folders at one go. I would suggest to create the top level folder first and then create the sub folder under it, then move on to the next level ...

You can find a useful implementation of creating nested folders in this link. You can modify it to feed a whole path of your target folder and then split the input by '/' character and navigate down by creating each folder on your path.

Like if your path is /A/B/C/D then you can feed '/A/B/C/D' string to your method, split by '/' to get array of folder names ['A', 'B', 'C', 'D'] and the start by creating folder 'A'. then folder 'B' underneath and so on.

I have tried to create something for your need based on the above example:

/// <summary>
/// Will ensure nested folder creation if folders in folderPath don't exist.
/// </summary>
/// <param name="ctx">Loaded SharePoint Client Context</param>
/// <param name="list">Document Library SharePoint List Object</param>
/// <param name="fullFolderPath">Complete folder path ParentFolder/ChildFolder1/ChildFolder2/...</param>
/// <returns>Last ChildFolder as target</returns>
private static Folder EnsureAndGetTargetFolder(ClientContext ctx, List list, string fullFolderPath)
{
    Folder returnFolder = null;

    if (string.IsNullOrWhiteSpace(fullFolderPath))
    {
        throw new ArgumentNullException(nameof(fullFolderPath));
    }

    string[] folderPath = fullFolderPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);

    if (folderPath != null && folderPath.Length > 0)
    {
        Web web = ctx.Web;
        Folder currentFolder = list.RootFolder;
        ctx.Load(web, t => t.Url);
        ctx.Load(currentFolder);
        ctx.ExecuteQuery();

        if(currentFolder.ServerObjectIsNull == null || currentFolder.ServerObjectIsNull.HasValue == false)
        {
            throw new Exception("Root folder not loaded.");
        }

        foreach (string folderName in folderPath)
        {
            FolderCollection folders = currentFolder.Folders;
            ctx.Load(folders);
            ctx.ExecuteQuery();

            if (folders.ServerObjectIsNull == null || folders.ServerObjectIsNull.HasValue == false)
            {
                throw new Exception("Unable to load folders.");
            }

            bool folderFound = false;
            foreach (Folder existingFolder in folders)
            {
                if (existingFolder.Name.Equals(folderName, StringComparison.InvariantCultureIgnoreCase))
                {
                    folderFound = true;
                    currentFolder = existingFolder;
                    break;
                }
            }

            if (!folderFound)
            {
                ListItemCreationInformation itemCreationInfo = new ListItemCreationInformation
                {
                    UnderlyingObjectType = FileSystemObjectType.Folder,
                    LeafName = folderName,
                    FolderUrl = currentFolder.ServerRelativeUrl
                };

                ListItem folderItemCreated = list.AddItem(itemCreationInfo);
                folderItemCreated.Update();
                ctx.Load(folderItemCreated, f => f.Folder);
                ctx.ExecuteQuery();
                currentFolder = folderItemCreated.Folder;
            }
        }

        returnFolder = currentFolder;
    }

    return returnFolder;
}

Let me know if this helps.

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.