Tuesday, May 14, 2013

Download Item Attachment and Upload it To Document Library

Download List Item Attachment and Upload it To Document Library
(with SharePoint Server Object Model and Client Object Model)

Purpose:

Migrate file attachments of SharePoint list item to SharePoint document library on the same server (Server Object Model) or on different servers (Client Object Model).

Server Object Model:

Using server object model, the code is relatively easy. The sample code assume there is one attachment file per list item.

        private void MigrateFile(SPWeb fromWeb, SPWeb toWeb, string fromListTitle, string toListTitle)
        {
            SPList fromList = fromWeb.Lists.TryGetList(fromListTitle);
            SPList toList = toWeb.Lists.TryGetList(toListTitle);
 
            if (fromList != null && toList != null)
            {
                foreach (SPListItem fromItem in fromList.Items)
                {  
                    string fromFileName = fromItem.Attachments[0];
                    SPFile fromFile = fromWeb.GetFile(fromItem.Attachments.UrlPrefix + fromFileName);
 
                    string toFileName = toList.RootFolder.ServerRelativeUrl + "/" + fromItem.Title + ".xml";
                    fromFile.CopyTo(toFileName, true);
                }
            }
        }

Client Object Model:

Using client object model you can migrate file between servers remotely. It is more flexible than server side object model but a little bit more difficult to write. For each sample code, you can easily write more code to copy the properties of the file too.

                ClientContext fromContext = new ClientContext("http://from.server.com");
                ClientContext toContext = new ClientContext("http://to.server.com");
 
                Web fromWeb = fromContext.Site.OpenWebById(fromWebInfo.Id);
                List fromList = fromWeb.Lists.GetById([listID]); //your own ID here
 
                // find the attachments folder of the list
                fromContext.Load(fromList, l => l.RootFolder.Folders.Where(f => f.Name == "Attachments"));
                fromContext.ExecuteQuery();
 
                if (fromList.RootFolder.Folders.Count > 0)
                {
                    // there is only one Attachments folder
                    Folder attachmentFolder = fromList.RootFolder.Folders[0];
 
                    fromContext.Load(attachmentFolder, f => f.Folders);
                    fromContext.ExecuteQuery();
 
                    foreach (Folder itemFolder in attachmentFolder.Folders)
                    {
                        FileCollection files = itemFolder.Files;
                        fromContext.Load(files);
                        fromContext.ExecuteQuery();
 
                        // assume there should be only one file in the special case
                        // Loop throught each file if there more than one
                        if (files.Count > 0)
                        {
                            Microsoft.SharePoint.Client.File file = files[0];
 
                            //download
                            FileInformation fromFileInfo = File.OpenBinaryDirect(fromContext, file.ServerRelativeUrl);
 
                            string fileUrl = "[ServerRelativeUrlOnTargetServer] + [filename.extension]"// your code here
 
                            //upload
                            File.SaveBinaryDirect(toContext, fileUrl, fromFileInfo.Stream, true);
                        }
                    }
                }

4 comments:

  1. The sample for client object model does not work for scanning folders in attachmentFolder.Folders

    Exception is: Missing method 'ListItemAllFields'.

    ReplyDelete
  2. Sorry but, Where could I execute this code? in powershell?

    ReplyDelete