Question

In a event receiver depending on some business rules, I need to copy the Document Set CONTENTS to another existing document set. However I cant find how to do it. I have the code that gets the source document set and the target document set. However I dont know how to copy the files.

And I can not use the DocumentSet.CopyTo, because the document set already exists, and it will overwrite the metadata on the existing document set.

private void CopyAgendaPointAttachmentsToRootSite(SPListItem agendaPointItem)
        {
            try
            {
                if (agendaPointItem != null)
                {
                    SPWeb currentSite = agendaPointItem.ParentList.ParentWeb;
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        using (SPSite site = new SPSite(currentSite.Site.RootWeb.Url))
                        {
                            using (SPWeb elevatedTargetWeb = site.OpenWeb())
                            {
                                SPList targetList = GetAgendaPointProposedTargetLibrary(agendaPointItem, elevatedTargetWeb);
                                DocumentSet targetDocumentSet = DocumentSet.GetDocumentSet(targetList.RootFolder);

                                SPDocumentLibrary targetDocumentLibrary = (SPDocumentLibrary)targetList;
                                SPContentTypeId targetCTId = targetList.ContentTypes.BestMatch(new SPContentTypeId(MeetingsCommon.Constants.CONTENTTYPES_AGENDAPOINTPROPOSED_ID));
                                DocumentSet documentSet = DocumentSet.GetDocumentSet(agendaPointItem.Folder);
                                if (documentSet != null)
                                {
                                    foreach (SPFile file in documentSet.Folder.Files)
                                    {
                                                      string copyToUrl = string.Concat(elevatedTargetWeb.Url, "/", targetList.RootFolder.Url, "/", agendaPointItem.Name, "/", file.Name);


                                    }
                                }
                            }
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                Logger.LogError("AgendaPointsEvents", "CopyAgendaPointAttachmentsToRootSite(SPListItem agendapointItem)", ex);
                throw;
            }
        }

Update:1 The exception thrown is Value does not fall within the expected range in the Copy Line, I checked with the debugger the url and its fine, because I can just copy and paste it in the browser and it works

Update 2:

Both DocumentSets are in different SPWeb objects
Was it helpful?

Solution

Ok, a few assumptions here, based on the code you posted:

  1. The target document set exists in a library in the root web of the site collection
  2. The origin document set exists in the same site collection, but in a sub-web somewhere
  3. The target document set already exists and is named exactly the same as the origin document set
  4. The SPListItem agendaPointItem passed into the method is the list item representing the origin document set

If these assumptions are correct, could you not just do:

SPWeb currentSite = agendaPointItem.ParentList.ParentWeb;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
    // you can stack your usings, you don't have to nest them
    using (SPSite site = new SPSite(currentSite.Site.RootWeb.Url))
    using (SPWeb elevatedTargetWeb = site.OpenWeb())
    {
        SPList targetList = GetAgendaPointProposedTargetLibrary(agendaPointItem, elevatedTargetWeb);

        // this line assumes that the target document set is in the root of the target library
        // and not inside some subfolder in the target library
        SPFolder targetFolder = targetList.RootFolder.Subfolders[agendaPointItem.Folder.Name];

        foreach (SPFile file in agendaPointItem.Folder.Files)
        {
            string copyToUrl = string.Format("{0}/{1}", targetFolder.ServerRelativeUrl, file.Name);
            file.CopyTo(copyToUrl, true);
        }

        elevatedTargetWeb.Update();
    }
});

This way you don't need to fool around with the DocumentSet objects at all, just move the files from one folder to another.

OTHER TIPS

    public static SPFile CopyFile(SPWeb web, string sourceUrl, DocumentSet docSet)
{
 SPFile file = web.GetFile(sourceUrl);
 string destinationFolderUrl = docSet.Folder.Url;

 destinationFolderUrl = (!destinationFolderUrl.EndsWith("/")) ? destinationFolderUrl + "/" : destinationFolderUrl;
 file.CopyTo(destinationFolderUrl + file.Name, true);
 web.Update();

 return web.GetFile(web.Url + "/" + destinationFolderUrl + file.Name);
}

http://howtosharepoint.blogspot.in/2010/12/programmatically-create-document-set.html

check this link

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