Monday, November 23, 2009

How To: Copy files across site collections in SharePoint

Technorati Tags: ,,,

SharePoint has great built in methods to copy or move documents across sub-sites or lists within the same site collection. You can use SPFile.MoveTo or SPFilem.CopyTo. You can even move whole folders and their contents with the SPFolder.MoveTo method. Very nice. Unfortunately, these do not work across site collections. However you can use the object model and a little bit of recursion to copy folders across site collections. The following code takes the url string to the source site collection, url string to the destination site collection, the name of the document library, the url string for the folder and the folder name.

public static void CopyFolderToAnotherSiteCollection(string sourceUrl, string destinationUrl,
          string listName, string folderUrl, string folderName)
      {
          string listRelatvieFolderUrl = folderUrl.Substring(folderUrl.IndexOf("/")+1);
          using (SPSite sourceSite = new SPSite(sourceUrl))
          {
              using (SPWeb sourceWeb = sourceSite.OpenWeb())
              {
                  SPFolder sourceFolder = sourceWeb.GetFolder(folderUrl);                            
                  using(SPSite destSite = new SPSite(destinationUrl))
                  {
                      using(SPWeb destWeb = destSite.OpenWeb())
                      {
                          SPListItem destItem = destWeb.Lists[listName].Items.
                              Add(string.Empty, SPFileSystemObjectType.Folder, listRelatvieFolderUrl);

                          destItem.Update();

                          SPFolder destFolder = destWeb.GetFolder(folderUrl);

                          foreach (SPFile file in sourceFolder.Files)
                          {  
                              destFolder.Files.Add(file.Url, file.OpenBinary());                            
                          }

                          foreach (SPFolder folder in sourceFolder.SubFolders)
                          {
                              CopyFolderToAnotherSiteCollection(sourceUrl, destinationUrl, listName,
                                  folder.Url, folder.Name);
                          }

                      }
                  }
              }
          }
      }

The SPFolder.Files.Add has many overloaded methods. You can decrease the amount of memory by using a stream object instead of the byte array returned by the SPFile.OpenBinary. You can also add metadata by populating a hashtable and sending that.

5 comments:

Anonymous said...

Thanks man!

Awesome!!!

Kourosh said...

HI, Thanks,
I had a problem an thought your code maybe solve my problem but it didn't.
the problem is Metadata values will not be copied with the file and they are empty.

For.Me said...

destFolder.Files.Add(file.Url, file.OpenBinary(), file.Properties);

this will copy metadata :)

Noel Gannon said...

Hi - I know this is an old post but I am wondering how to build this code? Is there a SharePoint dll needed in order to build in Visual Studio? Thanks! Noel

Alexandre Rousseau said...

Hi Steve,

Thanks for your great work.

I've got a problem with your code, especially for the "folderurl" definition.
CopyFolderToAnotherSiteCollection(oldUrl, newUrl, "Quality", @"/Quality/Forms/AllItems.aspx", "test");

Could you give me an exemple of this line?

Thanks in advance.

Alex.

Post a Comment