Reading Time: 2 minutes

While migrating share point documents we need to migrate document Library Files and Folders from one site to another.

It is easy to copy the files from one document library using the Open with Explorer command under the Library tab in Library Tools, but it won’t copy the meta data. Also we need to go ever library and do copy and paste.

To dynamically copy the files and folders using CSOM, follow below code.

Below code uses CSOM to copy all files and folders from one document library to another document library.  This code will allow you to copy an entire document library, along with user-defined metadata from one site collection to another.

Pass the user credentials, source and destination site URL and Libraries. I have tested in office 365 SharePoint Online.

public void CloneLibraryItems(string srcLibrary, string srcUrl, string destUrl, string userName, SecureString pwd)
string srclibraryname = string.Empty;
string fileName = string.Empty;
string folderPath = string.Empty;

ClientContext srcContext = new ClientContext(srcUrl);
ClientContext destContext = new ClientContext(destUrl);

srcContext.Credentials = new SharePointOnlineCredentials(userName, pwd);
srcContext.RequestTimeout = Timeout.Infinite;
Web srcWeb = srcContext.Web;
List srcList = srcWeb.Lists.GetByTitle(srcLibrary);
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = “<View Scope=’RecursiveAll’></View>”;
ListItemCollection itemColl = srcList.GetItems(camlQuery);

destContext.Credentials = new SharePointOnlineCredentials(userName, pwd);
destContext.RequestTimeout = Timeout.Infinite;
Web destWeb = destContext.Web;

string _path = destWeb.ServerRelativeUrl;
if (itemColl.Count > 0)

srclibraryname = itemColl[0].FieldValues[“FileDirRef”].ToString();
string[] srcurlSplit = srclibraryname.Split(‘/’);
srclibraryname = srcurlSplit[srcurlSplit.Count() – 1];

foreach (ListItem doc in itemColl)

if (doc.FileSystemObjectType == FileSystemObjectType.File)

fileName = doc[“FileRef”].ToString();
string[] fileNames = fileName.Split(new string[] { srclibraryname }, StringSplitOptions.None);
fileName = fileNames[fileNames.Count() – 1];

OSP.File file = doc.File;

FileInformation fileInfo = OSP.File.OpenBinaryDirect(srcContext, file.ServerRelativeUrl);
OSP.File.SaveBinaryDirect(destContext, _path + “/” + srclibraryname + fileName, fileInfo.Stream, true);

else if (doc.FileSystemObjectType == FileSystemObjectType.Folder)

folderPath = doc[“FileRef”].ToString();
string[] fileNames = folderPath.Split(new string[] { srclibraryname }, StringSplitOptions.None);
folderPath = fileNames[fileNames.Count() – 1];
folderPath = folderPath.TrimStart(new Char[] { ‘/’ });
//Console.WriteLine(“Folder Path :” + folderPath);
OSP.Folder folder = CreateFolder(destContext.Web, srcLibrary, folderPath);




catch (Exception ex)


Folder Creation

public OSP.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 OSP.Folder CreateFolderInternal(Web web, OSP.Folder parentFolder, string fullFolderPath)

var folderUrls = fullFolderPath.Split(new char[] { ‘/’ }, StringSplitOptions.RemoveEmptyEntries);
string folderUrl = folderUrls[0];
var curFolder = parentFolder.Folders.Add(folderUrl);

if (folderUrls.Length > 1)
var folderPath = string.Join(“/”, folderUrls, 1, folderUrls.Length – 1);
return CreateFolderInternal(web, curFolder, folderPath);

return curFolder;

Good luck

Also I built a Site Provisioning and Migration tool, please download and use it for all migrations.

If you looking for code