2

Any help would be appreciated here.

Below is my attempt to copy files and folders from one site collection to a completely different site collection. The structure from one side to the other should be the same for example if /cd/abc/def exists on the source it will be mirrored on the destination site.

My code works for copying folders and documents that exist on the root of the library. But when it encounters a folder that is not on the root or a file that exists inside a sub - sub folder it breaks.

Example Folder /docLibrary/Test works, but /docLibrary/test/test1 copies over as /docLibrary/test1. I know this problem comes from the CopyFolder method calling the folder.Folders.Add method but I'm not sure how to best approach adding a "sub folder" instead of a folder.

I am working with a SharePoint 2019 publishing site and using the Microsoft.SharePoint.Client object.

TLDR: I need to copy all files and folders from a library on one site collection to a library on a completely different site collection that shares the same structure, and I need it to copy sub folders as well. (EnsureFolder doesn't seem to exist in the client context version I'm using)

EDIT 2/3/2020 The marked answer did not quite work, because I couldn't get the MoveCopyUtil to work with multiple contexts, however the second link Clone or Copy SharePoint Document LIbrary had the needed logic. END EDIT

public void CopyDocuments(ClientContext srcContext, ClientContext destContext, string srcLibrary, string destLibrary)
{
    try
    {
        SP.List srcList = srcContext.Web.Lists.GetByTitle(srcLibrary);
        CamlQuery camlQuery = new CamlQuery();
        camlQuery.ViewXml = "<View Scope='RecursiveAll'><Query></Query></View>";
        ListItemCollection collListItems = srcList.GetItems(camlQuery);
        srcContext.Load(collListItems);
        srcContext.ExecuteQuery();
        foreach (ListItem item in collListItems) //Copy folders first 
        {
            try
            {
                if (item.FileSystemObjectType == FileSystemObjectType.Folder)
                {
                    Console.WriteLine("FOLDER FileRef" + item["FileRef"]);
                    CopyFolder(destContext, destLibrary, item);
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Copy Documents Error: Copying Folder :" + ex.Message);
            }

        }
        foreach(ListItem item in collListItems) //Copy items next
        {
            try
            {
                if (item.FileSystemObjectType == FileSystemObjectType.File)
                {
                    Console.WriteLine("FILE " + item["FileRef"]);
                    FileInformation fileInformation = SP.File.OpenBinaryDirect(srcContext, item["FileRef"].ToString());
                    srcContext.ExecuteQuery();
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        CopyStream(fileInformation.Stream, memoryStream);
                        memoryStream.Seek(0, SeekOrigin.Begin);
                        FileCreationInformation fileCreationInformation = new FileCreationInformation
                        {
                            ContentStream = memoryStream,
                            Overwrite = true,
                            Url = item["FileRef"].ToString()
                        };
                        SP.File uploadFile = destContext.Web.RootFolder.Files.Add(fileCreationInformation);
                        destContext.Load(uploadFile);
                        destContext.ExecuteQuery();
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("Copy Documents Error: Copying File :" + ex.Message);
            }
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

private static void CopyFolder(ClientContext destContext, string destLibrary, ListItem item)
{
    List destList = destContext.Web.Lists.GetByTitle(destLibrary);


    Folder folder = destList.RootFolder;            
    destContext.Load(folder);
    folder.Folders.Add(item["FileLeafRef"].ToString());
    //folder.AddSubFolder(item["FileLeafRef"].ToString());
    destContext.ExecuteQuery();
}
static private void CopyStream(Stream source, Stream destination)
{
    byte[] buffer = new byte[32768];
    int bytesRead;
    do
    {
        bytesRead = source.Read(buffer, 0, buffer.Length);
        destination.Write(buffer, 0, bytesRead);
    } while (bytesRead != 0);
}

#endregion

1 Answer 1

5

Install the SharePoint 2019 CSOM library using the NuGet below.

Install-Package Microsoft.SharePoint2019.CSOM -Version 16.0.10337.12109

Then use the methods of MoveCopyUtil class to copy/move folders and files.

Example:

string dstUrl = "http://sp2019/sites/team1";
string sourceFolder = "http://sp2019/sites/team1/libraryname/folder1";
string destFolder = dstUrl + "/libraryname/folder1";
using (ClientContext srcContext = new ClientContext(dstUrl))
{
    MoveCopyOptions option = new MoveCopyOptions();
    option.KeepBoth = true;
    MoveCopyUtil.CopyFolder(srcContext, sourceFolder, destFolder, option);
    srcContext.ExecuteQuery();
}

Reference:Copy or Move Folder Structure in SharePoint Using CSOM

Or check the article below with the code to achieve it.

Clone or Copy SharePoint document Library Files and Folders from one site to another using CSOM

2
  • I will give this a try tomorrow and get back to you, in my research I didn't think that the MoveCopyOptions would allow me move between different site collections, as soon as I give this a shot I will Update. Thanks again! Jan 23, 2020 at 5:26
  • I apologize for the late response, I ended up sick the last couple weeks. Your second link worked out for what I needed. The MoveCopyUtil unfortunately does not work when there are multiple contexts being dealt with, while the second article you linked worked out. Thanks again for the help. Feb 3, 2020 at 19:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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