Question

I am making a tool to migrate/update specific content (list items and documents) from a farm to another. A little bit like the SharePoint Content Deployment Wizard, but with custom specifications from my client.

Using the Content Deployment API seems a good idea.

The site collections in each farm were created using standard process (using a custom site definition provisionning list and elts). I don't think I should use "RetainObjectIdentity" because the Guids are different between the 2 farms.

When I export/import data :

  • Documents are correctly added/updated, but it's not the case for list items :
  • It doesn't update existing list items. It always add new one.

So here is my question : What is the best solution to update existing list items (they don't have same GUIDs between site collections) ? I would like to retain the ListItem.ID (not UniqueID). Is that possible ? Is there a solution to tell the API to restore This Item to this one ? On the worst case, I can delete existing items before importing, but the items would lose their original ListItem.ID (int)...

Or I can forget the Content Deployment API...

Below : the code I am using :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Deployment;
using Microsoft.SharePoint;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
        Export();
        Import();
    }

    static void Import()
    {
        using (SPSite site = new SPSite("http://localhost:5555/sites/aa/"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPImportSettings settings = new SPImportSettings();
                settings.SiteUrl = site.Url;
                settings.FileLocation = @"c:\export";
                settings.BaseFileName = "blop.cmp";
                settings.RetainObjectIdentity = false;
                settings.CommandLineVerbose = true;

                SPImport import = new SPImport(settings);
                import.Run();  
            }
        }
    }


    static void Export()
    {
        using (SPSite site = new SPSite("http://localhost:5555"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList listDocs = web.Lists["Shared Documents"];
                SPListItem item = listDocs.Items[0];
                SPExportObject obj = new SPExportObject();
                obj.Id = item.UniqueId;
                obj.Type = SPDeploymentObjectType.ListItem;

                SPList listTasks = web.Lists["Tasks"];
                SPListItem item2 = listTasks.Items[0];
                SPExportObject obj2 = new SPExportObject();
                obj2.Id = item2.UniqueId;
                obj2.Type = SPDeploymentObjectType.ListItem;


                SPExportSettings settings = new SPExportSettings();
                settings.IncludeVersions = SPIncludeVersions.LastMajor;
                settings.SiteUrl = site.Url;
                settings.IncludeSecurity = SPIncludeSecurity.None;
                settings.FileLocation = "C:\\export";
                settings.BaseFileName = "blop";
                settings.CommandLineVerbose = true;
                settings.ExportObjects.Add(obj);
                settings.ExportObjects.Add(obj2);
                settings.OverwriteExistingDataFile = true;

                SPExport export = new SPExport(settings);
                export.Run();

            }
        }
    }
  }
}
Was it helpful?

Solution

I found one solution :

Microsoft let us modify the XML files used to import data :

Screenshot temp folder

So what I did :

  • Set the import settings.RetainObjectIdentity to true.
  • Modify the xml files to change the Guids of existing content

Right now, there's a lot of hardcoded things, but I think, I will be able to make it more generic.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Deployment;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.IO;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
        Export();
        Import();
    }

    static void Import()
    {
        using (SPSite site = new SPSite("http://localhost:5555/sites/aa"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPImportSettings settings = new SPImportSettings();
                settings.SiteUrl = site.Url;
                settings.FileLocation = @"c:\export";
                settings.BaseFileName = "blop.cmp";
                settings.RetainObjectIdentity = true;

                settings.CommandLineVerbose = true;

                SPImport import = new SPImport(settings);
                import.Started += new EventHandler<SPDeploymentEventArgs>(import_Started);
                import.Run();  
            }
        }
    }

    static void import_Started(object sender, SPDeploymentEventArgs e)
    {
        Guid IDListOld = Guid.Empty;
        Guid IDItemOld = Guid.Empty;
        Guid IDWebOld = Guid.Empty;
        Guid IDRootFolderOld = Guid.Empty;
        Guid IDFolderTaskOld = Guid.Empty;
        string IDCtypeOld = "";

        Guid IDListNew = Guid.Empty;
        Guid IDItemNew = Guid.Empty;
        Guid IDWebNew = Guid.Empty;
        Guid IDRootFolderNew = Guid.Empty;
        Guid IDFolderTaskNew = Guid.Empty;
        string IDCtypeNew = "";

        using (SPSite site = new SPSite("http://localhost:5555"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList list = web.Lists["Tasks"];
                IDWebOld = web.ID;
                IDListOld = list.ID;
                IDItemOld = list.Items[0].UniqueId;
                IDCtypeOld = list.Items[0].ContentType.Id.ToString();
                IDRootFolderOld = list.RootFolder.UniqueId;
                IDFolderTaskOld = web.GetFolder("Lists/Tasks/Task").UniqueId;
            }
        }

        using (SPSite site = new SPSite("http://localhost:5555/sites/aa/"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList list = web.Lists["Tasks"];
                IDWebNew = web.ID;
                IDListNew = list.ID;
                IDItemNew= list.Items[0].UniqueId;
                IDCtypeNew = list.Items[0].ContentType.Id.ToString();
                IDRootFolderNew = list.RootFolder.UniqueId;
                IDFolderTaskNew = web.GetFolder("Lists/Tasks/Task").UniqueId;
            }
        }

        DirectoryInfo d = new DirectoryInfo(e.TempDirectoryPath);
        foreach (FileInfo info in d.GetFiles())
        {
            string content = "";
            using (TextReader reader = File.OpenText(info.FullName))
            {
                content = reader.ReadToEnd();
                content = content.Replace(IDItemOld.ToString(), IDItemNew.ToString());
                content = content.Replace(IDWebOld.ToString(), IDWebNew.ToString());
                content = content.Replace(IDListOld.ToString(), IDListNew.ToString());
                content = content.Replace(IDCtypeOld.ToString(), IDCtypeNew.ToString());
                content = content.Replace(IDRootFolderOld.ToString(), IDRootFolderNew.ToString());
                content = content.Replace(IDFolderTaskOld.ToString(), IDFolderTaskNew.ToString());
            }
            File.WriteAllText(info.FullName, content);

        }
    }


    static void Export()
    {
        using (SPSite site = new SPSite("http://localhost:5555"))
        {
            using (SPWeb web = site.OpenWeb())
            {
                SPList listTasks = web.Lists["Tasks"];
                SPListItem item2 = listTasks.Items[0];
                SPExportObject obj2 = new SPExportObject();
                obj2.Id = item2.UniqueId;
                obj2.Type = SPDeploymentObjectType.ListItem;

                SPExportSettings settings = new SPExportSettings();
                settings.IncludeVersions = SPIncludeVersions.LastMajor;
                settings.SiteUrl = site.Url;
                settings.IncludeSecurity = SPIncludeSecurity.None;
                settings.FileLocation = "C:\\export";
                settings.BaseFileName = "blop";
                settings.CommandLineVerbose = true;
                settings.ExportObjects.Add(obj2);
                settings.OverwriteExistingDataFile = true;

                SPExport export = new SPExport(settings);
                export.Run();
            }
        }
    }
   }
}

[By the way, I don't know if I should have edited my question instead]

OTHER TIPS

The reason for this is the way the SharePoint API itself handles versions. When you call SPFolder.Add() with a duplicated filename and versioning is enabled, then a new version is added (rather than a new file added).

One thing you may want to try is enabling versioning on the List before the import - this may allow updates (with versions saved).

If not, I'm afraid, as you have identified, the only way will be to clear the list before running the import.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top