Tuesday, May 29, 2012

Export Import SharePoint Site using Web Service

Problem:

While working with SharePoint Online – sometimes it is required to take the backup of the site or to export the site to some other environment, but due to no access to SharePoint server, we end up with writing huge code to migrate the site contents to another site using any client object model.
If server side scenario is considered, we have lots of options to perform a simple site export and import operation , like say – use stsadm commands , use Central Administration , use powershell scripts but for SharePoint Online environment what to do? Well here comes web services in picture , how? We will see in details.

Solution:
SharePoint Web services are already there since MOSS 2007, but mostly not used. Here we are going to use the sites.asmx web service to export and import the sites.
Note that before performing these operations using web services – make sure that you have site collection administrator rights on source as well as target site.
I created a Team site as source site and added some sample data to it , say about 4000 documents + 3000 list items with attachments + some content types + some site columns + some lookup columns + some list and content type workflows.

We can use the ExportWeb function given by the sites.asmx web service which takes some parameters as input – let’s see what those are.
  • 1.       jobName: this is the string parameter and can be set to any string , using this name the cmp files will be created. Please make a note that no special characters are allowed here.
  • 2.       webUrl: url of the site which needs to be exported as cmp files.
  • 3.       Datapath: path where all cmp files will be stored (typically a path of the document library on source site)
  • 4.       Includesecurity: as name suggests – Boolean parameter to include security or not
  • 5.       Overwrite: Boolean parameter to overwrite cmp files on save location
  • 6.       cabSize: size of each cmp file , can be set to 2GB max.
  • Export web function returns an integer after completion , but mostly the description is not available for the return types. 
Here it is :

Value
Description
1
Pending: The operation is in progress.
4
InvalidExportUrl: The site specified in the webUrl is not accessible.
5
ExportFileNoAccess: The location specified in the dataPath is not accessible.
6
ExportWebNoAccess: The user does not have the required permissions to execute this operation successfully. The user MUST have the ManageLists and AddListItems permissions in the solution gallery.
7
ExportError: An error other than the errors listed in this table occurred during exporting the site. An example of a condition that would result in this error is if there was no content on the site to export.
8
UploadDataError: The content migration package file is not uploaded to the server successfully. This can occur if the specified path was invalid, read-only, the caller is not authorized to access it, or the file is already open.

ImportWeb:
While importing the web from cmp files using web services – we can use ImportWeb function of sites.asmx web service.

Important part here is – the target site on which import is to be done – should be created using OOB blank site definition. There can be an error while performing the import operation like – the source site is created using template STS#0 and target site is created using STS#1 , - solution to this is – create target site collection without any template – select the select template later option while creating target the site collection.
ImportWeb function take some parameters let’s see what those are
  • 1.       jobName: string parameter , can be set to anything – but no special characters should be included.
  • 2.       webUrl: url of target web.
  • 3.       dataFiles: this is array of string containing url of all cmp files. Example : If there are 10 cmp files in the source location – then dataFiles parameter will be any array having urls of 10 files in ascending order.
  • 4.       logPath: path where log file can be created. This can be passed as null. (typically a url of any document library)
  • 5.       includesecurity: to include security or not
  • 6.       overwrite: overwrite log files.
Similar to ExportWeb function – ImportWeb function also return an interger on completion.
Here are the details

Value
Description
1
Pending: The operation is in progress.
2
GenericError: An error other than the errors listed in this table occurred importing the site.
4
InvalidImportUrl: The site specified in the webUrl is not accessible.
5
ImportFileNoAccess: At least one location specified in dataFiles is not accessible.
6
ImportWebNoAccess: The user has insufficient permission to import to the location specified in webUrl.
8
mportWebNotEmpty: The location specified by webUrl corresponds to an existing site that is not a blank site.
11
LogFileNoAccess: The location specified by logPath is not accessible.

Ok , so after lots of theory – here is the simple console application example which I tried on my environment successfully.

static void Main(string[] args)
{
    string sourcesiteurl = "http://sourcesitecollection/";
    string targetsiteurl = "http://targetblanksitecollection/";
    string svcUrl = "_vti_bin/sites.asmx";

    Sites sites = new Sites();
    NetworkCredential credentials = new NetworkCredential("username", "password", "domain");
    sites.Credentials = credentials;
    sites.Timeout = 600000;

    Console.WriteLine("Choose..1. Export , 2. Import");
    string responce = Console.ReadLine();

    if (responce.Equals("1"))
    {
       sites.Url = string.Format("{0}{1}", sourcesiteurl, svcUrl);
       try
       {
         int result = sites.ExportWeb("MyExportTest", sourcesiteurl, "http://sourcesite/Exports", true, true, true, 1024);
         Console.WriteLine("done with result - " + result.ToString());
       }
       catch (Exception ex)
       {
          Console.WriteLine(ex.Message);
          Console.WriteLine();
          Console.WriteLine(ex.StackTrace);
       }
     }

     else if (responce.Equals("2"))
     {
         sites.Url = string.Format("{0}{1}", targetsiteurl, svcUrl);
         string[] dataFiles = new string[] { "http://sourcesite/Exports/MyExportTest.cmp" };
         
          try
          {
            int result = sites.ImportWeb("MyExportTest", targetsiteurl, dataFiles, null, true, true);
            Console.WriteLine("done with result - " + result.ToString());
          }
          catch (Exception ex)
          {
            Console.WriteLine(ex.Message);
            Console.WriteLine();
            Console.WriteLine(ex.StackTrace);
          }
       }
     Console.ReadLine();
   }