Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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
share|improve this question

2 Answers 2

up vote 1 down vote accepted

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.

share|improve this answer
    
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? –  L.V. Sharepoint Architect Mar 27 '13 at 6:53
    
I had to use SPweb.files.add with a full url and then it works –  L.V. Sharepoint Architect Mar 27 '13 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. –  Dylan Cristy Mar 27 '13 at 13:55
    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

share|improve this answer
    
I think I am mmissing the file name at the end, testing.... –  L.V. Sharepoint Architect Mar 26 '13 at 13:16
    
pls see my update1 –  L.V. Sharepoint Architect Mar 26 '13 at 13:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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