1

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

2 Answers 2

2

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.

3
  • I tried your code but I get this: Value does not fall within the expected range. in the copyto call. The value of the copyToUrl variable is: /AgendaPointsProposedCor/379db39b-15ed-4f5f-a244-3ab3d87f1533/sample-loterij.txt I wonder if it should have maybe the myservername and then the rest? Commented Mar 27, 2013 at 6:53
  • I had to use SPweb.files.add with a full url and then it works Commented Mar 27, 2013 at 7:42
  • I'm wondering if it also might work (using the server relative url) by doing targetFolder.Files.Add. Glad you got it working in the end, though. Commented Mar 27, 2013 at 13:55
2
    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

2
  • I think I am mmissing the file name at the end, testing.... Commented Mar 26, 2013 at 13:16
  • pls see my update1 Commented Mar 26, 2013 at 13:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.