Move a SPListItem without loosing its ItemId – Custom List

Once I got a requirement to move a list item from one folder location to another within the same list (e.g. move the item to a sibling) while retaining the same ItemID.

Example:

Here is the original structure...

List 1
Folder 1
Item A
Folder 2

We need to move Item A to Folder 2 also the ItemID need be retained.

List 1
Folder 1
Folder 2
Item A

If it is a custom list item ( in list template ID 100 – custom list) then through code we can’t copy the item using SPListItem.CopyTo() method and that information is added in the community content in our MSDN SDK article : https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistitem.copyto.aspx , we can see some people already mentioned about that concern so I hope this solution will be a work-around for that method as well.

We can work-around it in another way , export the Item A from the List and then import it to the same list after deleting & re-parenting the item. You can copy paste this code to a .NET console based application and modify the necessary stuffs. Also this way you can retain the ID of the list item as well.

    1: using System;
    2: using System.Collections.Generic;
    3: using System.Text;
    4: using Microsoft.SharePoint;
    5: using Microsoft.SharePoint.Deployment;
    6: namespace MoveItem
    7: {
    8:     class Program
    9:     {
   10:         static string siteUrl = "https://site";
   11:  
   12:         static void Main(string[] args)
   13:         {
   14:             string exportFolder = @"C:\export\";
   15:             string exportFileName = "Export_File.cmp";
   16:  
   17:             using (SPSite site = new SPSite(siteUrl))
   18:             {
   19:                 using (SPWeb oWeb = site.OpenWeb())
   20:                 {
   21:                     SPList oList = oWeb.Lists["MyList"];
   22:  
   23:                     SPListItem oItemA = oList.GetItemById(7);// ItemA
   24:  
   25:                     SPExportObject exportObject = new SPExportObject();
   26:                     exportObject.Id = oItemA.UniqueId;
   27:                     exportObject.Type = SPDeploymentObjectType.ListItem;
   28:  
   29:                     SPExportSettings exportSettings = new SPExportSettings();
   30:                     exportSettings.LogExportObjectsTable = true;
   31:                     exportSettings.LogFilePath = @"C:\export\log.log";
   32:                     exportSettings.SiteUrl = siteUrl;
   33:                     exportSettings.ExportMethod = SPExportMethodType.ExportAll;
   34:                     exportSettings.FileLocation = exportFolder;
   35:                     exportSettings.BaseFileName = exportFileName;                    
   36:                     exportSettings.ExportObjects.Add(exportObject);
   37:  
   38:                     SPExport export = new SPExport(exportSettings);
   39:                     export.Run();
   40:  
   41:                     // delete the item from Folder 1
   42:                     oItemA.Delete();                    
   43:  
   44:                     SPImportSettings settings = new SPImportSettings();
   45:                     settings.SiteUrl = siteUrl;
   46:                     settings.WebUrl = siteUrl;
   47:                     settings.FileLocation = @"c:\export";
   48:                     settings.LogFilePath = @"C:\export\log.log";
   49:                     settings.RetainObjectIdentity = false;
   50:                     settings.BaseFileName = exportFileName;                    
   51:  
   52:                     SPImport import = new SPImport(settings);
   53:   // handle the import event to re-parent the item
   54:                     import.Started += new EventHandler<SPDeploymentEventArgs>(import_Started);
   55:                     import.Run();
   56:                 }
   57:             }
   58:                 
   59:             }
   60:  
   61:         static void import_Started(object sender, SPDeploymentEventArgs e)
   62:         {
   63:           
   64:             using (SPSite site = new SPSite(siteUrl))
   65:             {
   66:                 using (SPWeb oWeb = site.OpenWeb())
   67:                 {
   68:                     SPList oList = oWeb.Lists["MyList"];
   69:  
   70:                     foreach (SPImportObject io in e.RootObjects) 
   71:                    { 
   72:                       if (io.Type == SPDeploymentObjectType.ListItem)               
   73:                       {
   74:                           io.TargetParentUrl = oList.RootFolder.ServerRelativeUrl + "/Folder2/";  
   75:                           
   76:                       }                                                                                                                                           
   77:                    } 
   78:  
   79:                 }
   80:             }
   81:         }
   82:     }
   83: }
   84:  

Comments

  • Anonymous
    October 04, 2009
    Good work guys, thanks for it.

  • Anonymous
    October 14, 2009
    The problem you describe is also one I try to find solutions. I understand that, with code, its possible to "move" an SPListItem. But my concern is more for the end-user interface. What is more intuitive than a drag and drop to switch folder. Having a special program to move item when the user forget to create the item in the right folder cannot be a good solution for my needs. At a conversion stage, its fine for me because its will run once. If the intuitive drag and drop is not available in SharePoint 2010, the best I can see is a kind of tree view, wich have the structure of the folder to let the user able to select where to put the the item and some code, like yours, wich will run at the save event. If theres a simple solution I missed, please tell me. Thanks

  • Anonymous
    August 25, 2010
    Superb, been looking for this for ages.

  • Anonymous
    April 07, 2011
    Hi Thanks your post, I follow your steps but I have a Lookup fields in source list these lookup fields are copyinf to destination but targetting th elookup values are Source lookup list even I have a Lookup listItem in destination with same Ids. With BestRegards, MTR.

  • Anonymous
    March 09, 2012
    every List item have url . we can use this url to move SPlistitem to subfolder in same list or other list location for detail code refer to below blog think4code.blogspot.com/.../move-list-item-splistitem-to-sub-folder.html

  • Anonymous
    August 21, 2012
    I cannot move more than 130 item, any idea?