Move Folders of SharePoint Document Library using object model

Move Folders of SharePoint Document Library using object model
3 votes, 5.00 avg. rating (97% score)

Introduction

SharePoint does not support moving folders directly but in this post we will see how we can achieve move folders of SharePoint document library to one location to another using object model.
We will also see how to keep same folder Version, Modified and ModifiedBy values after moving
The post includes

  • Moving folder along with subfolders from source to destination
  • Moving folder along with its items
  • Creation of folder
  • Deleting of folder

Skill Level – Medium

Move folder

Object model has MoveTo option on Folder object but that will not move the folder. From UI if we check Content and structure we will get move option on the file but
move option will be in disabled state on the folder.

Below code uses ‘MoveFolder’ method to move folder from source to destination. The method uses internally other methods to move all the subfolders and items.
Source folder ‘DevTeam’ is located in ‘Shared Documents’ Documents Libary
‘DevTeam’ folder should be moved to ‘ProjTeam’ folder under ‘ProjectDocs’ Documents Library. ‘ProjTeam’ is our destination folder.

		
	string siteUrl = "http://sharepoint-devsite.com/DevSiteA";
	string sourceDirectory = "/DevSiteA/Shared Documents/DevTeam";
	string destinationDirectory = "/DevSiteA/ProjectDocs/ProjTeam";

	using (SPSite currSite = new SPSite(siteUrl))
	{
		using (SPWeb currWeb = currSite.OpenWeb())
		{
		  	MoveFolder(currWeb, sourceDirectory, destinationDirectory);
		}
	}

	//Move all folders and subfolder
	public void MoveFolder(SPWeb sourceWeb, string sourceDirectory, string destinationDirectory)
	{
		SPFolder srcFolder  = sourceWeb.GetFolder(sourceDirectory);
		if (srcFolder.Exists)
		{
			SPDocumentLibrary docLib = srcFolder.DocumentLibrary;
			SPFolderCollection oFolder = srcFolder.SubFolders;
			SPQuery oQuery = new SPQuery();
			oQuery.Query = "<Where><Eq><FieldRef Name='FSObjType'/><Value Type='Lookup'>1</Value></Eq></Where>";
			oQuery.Folder = oFolder.Folder;
			oQuery.ViewAttributes = "Scope='RecursiveAll'";
			SPListItemCollection collListItems = docLib.GetItems(oQuery);
			string newdestinationFolderPath = destinationDirectory;
			//Move the root folder with files
			MoveSingleFolder(sourceWeb, sourceDirectory, newdestinationFolderPath);

			newdestinationFolderPath = destinationDirectory + "/" + srcFolder.Name;
			//Move the subfolders with files
			foreach (SPListItem item in collListItems)
			{
				MoveSingleFolder(sourceWeb, item.Url, newdestinationFolderPath);
			}
			// Delete the root folder
			DeleteSourceFolder(sourceWeb, sourceDirectory);
		}

	   
	}

	//Move single folder
	private void MoveSingleFolder(SPWeb srcWeb, string sourceFolderPath, string destinationFolderPath)
	{
		SPFolder srcFolder = srcWeb.GetFolder(sourceFolderPath);
		if (srcFolder.Exists)
		{
			string srcFolderName = srcFolder.Name;
			SPFolder dstFolder = srcWeb.GetFolder(destinationFolderPath);
			if (dstFolder.Exists) 
			{
				//create the folder    
				SPFolder newFolder = dstFolder.SubFolders.Add(srcFolderName);
					SPListItem newFolderItem = (SPListItem)newFolder.Item;
					newFolderItem.ParentList.Fields[SPBuiltInFieldId.Modified].ReadOnlyField = false;
					newFolderItem.ParentList.Fields[SPBuiltInFieldId.Modified_x0020_By].ReadOnlyField = false;
					newFolderItem[SPBuiltInFieldId.Modified] = srcFolder.Item["Modified"];
					newFolderItem["Modified By"] = srcFolder.Item["Modified By"];
					newFolderItem.UpdateOverwriteVersion();
					newFolderItem.ParentList.Fields[SPBuiltInFieldId.Modified].ReadOnlyField = true;
					newFolderItem.ParentList.Fields[SPBuiltInFieldId.Modified_x0020_By].ReadOnlyField = true;
				
			}
			MoveFolderItems(srcWeb, sourceFolderPath, destinationFolderPath + "/" + srcFolderName);
		}
	}

	//Move folder items
	private void MoveFolderItems(SPWeb sourceWeb, string sourceFolderPath, string destinationFolderPath)
	{
		SPFolder srcFolder = sourceWeb.GetFolder(sourceFolderPath);
	  	int fileCount = srcFolder.Files.Count;
		while (fileCount > 0)
		{
			SPFile sourceFile = sourceWeb.GetFile(srcFolder.Files[0].Url);
			object modifiedOn = sourceFile.Item["Modified"];
			object modifiedBy = sourceFile.Item["Modified By"];

			sourceFile.MoveTo(destinationFolderPath + "/" + sourceFile.Name, true);

			fileCount--;

			SPListItem dstItem = (SPListItem)sourceFile.Item;
			dstItem.ParentList.Fields["Modified"].ReadOnlyField = false;
			dstItem.ParentList.Fields["Modified By"].ReadOnlyField = false;
			dstItem["Modified"] = modifiedOn;
			dstItem["Modified By"] = modifiedBy;
			dstItem.UpdateOverwriteVersion(); //updates the item without creating another version of the item
			dstItem.ParentList.Fields["Modified"].ReadOnlyField = true;
			dstItem.ParentList.Fields["Modified By"].ReadOnlyField = true;
		}
	}
        
	//Delete the folder
	private void DeleteSourceFolder(SPWeb srcWeb, string sourceFolderPath)
	{
		SPFolder srcFolder = srcWeb.GetFolder(sourceFolderPath);
		if (srcFolder.Exists)
		{
			if (srcFolder.Files.Count == 0) //Delete only after moving
			{
				SPFolder srcRootFolder = srcFolder.ParentFolder;
				srcRootFolder.SubFolders.Delete(srcFolder.Url);
			}
		}

	}


Move Folder creates folder, moves items to it. It will then creates all the subfolders and moves items to each subfolder from the source. After moving is done the source folder is deleted. Version along with ‘Modified’ and ‘Modified By’ values will be same as the source.

Before Moving
Source Folder


After Moving
Destination Folder

Conclusion

Moving folders along with subfolders is a requirement which cannot be done directly from UI or from object model. Hope this code helps when required.

August 10, 2013 В· Adi В· 4 Comments
Tags: , , , , ,  В· Posted in: C#, Sharepoint 2007, Sharepoint 2010, SharePoint 2013

4 Responses

  1. Sarah - January 20, 2016

    Thanks for your useful post. Does your code work for sharepoint online?

  2. Adi - January 29, 2016

    It’s custom code for farm based solution. However if you are using for SharePoint online you have tweak the code with client object model. The logic and approach will be same.

    Regards,
    Adi

  3. John - April 14, 2016

    Can this be accomplished using PowerShell?

  4. Adi - May 4, 2016

    Hi John,

    Yes this can be done with powershell also.
    Regards,
    Adi

Leave a Reply

What is 8 + 12 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)