Part 2: Copy a SharePoint List Programmatically

I started this series to show how to copy different kinds of lists in SharePoint. Each type of list has its own challenges. In this article I will also demonstrate how to copy custom fields and keep the same internal name. It’s kind of annoying that you can’t create a field with the internal name you specify, but I found a pretty easy workaround. You create the field using AddFieldAsXml on the list Fields collection, and you use the internal name as the display name. This creates the field with the correct internal name. Then just change the Title property of the field to what you want displayed. Problem solved.

Copying a document library is similar to copying a generic list, except that you also need to copy the document file attached to the list item. You also need to determine the template that was used to create the original list, and use that template to create the new list. That way, when users add a new document, it is of the right document type. Another gotcha in copying document libraries, is that there is a subfolder structure that needs to be copied recursively to get everything in its correct place.

Here's the code. I copied it out of my project, which has everything in its own method, so I apologize if some of my capitalization or field names are not correct. Also, there is a function referenced, CopyFieldValues. If you need to know how to do this, refer to Part 1 of this series. Document libraries can have field values just like other lists, so you'll need to copy those too if you want a complete copy of the list.

// get the document template to use when creating the new list
SPDocTemplate docTemplate;
SPDocTemplateCollection templates = destinationWeb.DocTemplates;
XDocument templateSchema = XDocument.Parse(templates.SchemaXml);
IEnumerable<XElement> paths = templateSchema.Descendants("DocumentTemplateFile");

string sourceUrl = sourceDocumentTemplateUrl.Substring(sourceDocumentTemplateUrl.IndexOf("/") + 1);
XElement path = paths.Where(p => p.Attribute("TargetName").Value == sourceUrl).Single();
XElement docTemplate = path.Parent.Parent;
int type = Convert.ToInt32(docTemplate.Attribute("Type").Value);

SPDocTemplate destTemplate = null;
foreach (SPDocTemplate template in templates)
{
   if (template.Type == type)
      docTemplate = template;
}

Guid newListID = destinationWeb.Lists.Add(sourceList.Title,
                     sourceList.Description,
                     destinationWeb.ListTemplates["Document Library"], docTemplate);

SPList destinationList = destinationWeb.Lists[newListID];

// add any custom fields that were created
foreach (SPField field in SourceList.Fields)
{
   if (!DestinationList.Fields.ContainsField(field.InternalName))
   {
      // create field with correct internal name
      XDocument fieldXdoc = XDocument.Parse(field.SchemaXml);
      XElement fieldElement = fieldXdoc.Element("Field");
      XAttribute displayName = fieldElement.Attribute("DisplayName");
      displayName.Value = field.InternalName;
      string fieldName = DestinationList.Fields.AddFieldAsXml(fieldXdoc.ToString());
      SPField newfield = DestinationList.Fields.GetField(fieldName);
      newfield.Title = field.Title;
   }
}

Here is the code for CopyDocumentLibraryItems, which needs to be recursive to get all the items in all the subfolders:

      protected virtual void CopyDocumentLibraryItems(SPFolder sourceFolder, SPFolder destFolder)
      {
         // get a list of items in the source folder
         SPListItemCollection items = ((SPDocumentLibrary)SourceList).GetItemsInFolder(SourceList.DefaultView, sourceFolder);

         foreach (SPListItem item in items)
         {
            SPFileSystemObjectType myType = item.FileSystemObjectType;
            string relativeDestinationUrl = "{0}/{1}";
            if (myType == SPFileSystemObjectType.File)
            {
               SPFile fi = item.File;
               byte[] filebytes = fi.OpenBinary();
               relativeDestinationUrl = string.Format(relativeDestinationUrl, destFolder.Url, fi.Name);
               SPFile newFile = destFolder.Files.Add(relativeDestinationUrl, filebytes, true);
               SPListItem newItem = newFile.Item;
               CopyFieldValues(item, newItem);
               newItem.UpdateOverwriteVersion();
            }
            else
            {
               relativeDestinationUrl = string.Format(relativeDestinationUrl, destFolder.Url, item.Folder.Name);
               SPFolder destSubFolder = destFolder.SubFolders.Add(relativeDestinationUrl);
               SPFolder sourceSubFolder = item.Folder;
               // copy everything in sub folder
               CopyDocumentLibraryItems(sourceSubFolder, destSubFolder);
            }
         }
      }

Technorati Tags:
Print | posted on Sunday, March 15, 2009 8:14 AM

Feedback

#  SharePoint List item insertion Programmatically

left by Test at 3/18/2009 12:50 AM Gravatar
using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Security;

using Microsoft.SharePoint;

[assembly: AllowPartiallyTrustedCallers]

namespace TestClassLibrary

{

public class HelloWorldWebPart : WebPart

{

protected override void Render(HtmlTextWriter writer)

{

currentWeb.AllowUnsafeUpdates = true;

SPWeb currentWeb = SPContext.Current.Web;

SPList list = currentWeb.Lists[VivekList];

SPListItem newListItem = list.Items.Add();

newListItem["Title"] = "Root";

newListItem["City"] = "Root";

newListItem.Update();

}

}

}

by this you can access list in sharepoint and insert items in that ..this is very usefull article.. i have't founde this on net so i am posting this..but this will insert item when list will be there. so first need to create a list with two column title and city...and then through C# prgm u can add items programtically

Enjoy Sharepoint!

# re: Part 2: Copy a SharePoint List Programmatically

left by ssss at 5/14/2009 7:19 PM Gravatar
Where is part 1?????

Please provide the Url of that... :)

# re: Part 2: Copy a SharePoint List Programmatically

left by Dejan Dujak at 6/4/2009 2:18 AM Gravatar
Hallo Anne,

Iám trying to sync Pages from one farm server to other farm server. Do you have source code how to sync page library from one server to other.

Please help.

Kind regards,

Dejan Dujak

# re: Part 2: Copy a SharePoint List Programmatically

left by myro at 9/1/2009 12:50 AM Gravatar
@Dejan Dujak
you should call sharepoint's webservices:
http://msdn.microsoft.com/en-us/library/copy.aspx
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: