Monday 25 November 2013

Move Folders of SharePoint Document Library using object model

Move Folders of SharePoint Document Library using object model


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 Modified By 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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.

 

3 comments:

  1. Here's a way to do it:

    1. Sync your document app in SP 2013 to your PC.
    2. Go into that folder on your PD and move/create folders as required.
    3. Your PC will sync that back to your SP site.

    Took me a while to work out how to to it but it works!

    Ray

    ReplyDelete
  2. Thanks for sharing helpful script to move folders to SharePoint Online. I already tried this exchange public folder to SharPoint migration tool (http://www.lepide.com/lepidemigratordocuments/) that enables to move public folder to SharePoint with the complete attachment and performs Exchange to SharePoint 2013 with their all data intact and by providing the character mapping features.

    ReplyDelete
  3. Take along a GPS receiver, make good notes, and then get to work on Google Earth. ... Name your folder something like Desert Volcano Adventure or Awesome Hiking Route. ... KMLfile. KML stands for Keyhole Markup Lan Plastic document folder for Hiking and travelling

    ReplyDelete