Moving A SharePoint Discussion To Another List

In SharePoint there is no easy way to copy over a discussion board thread over to another board.  So for instance, if there is a thread that is in the wrong place, and needs to be moved over to a different discussion board that is of a different topic, you are fresh out of luck.  The tradition copy items through the “Manage Site Content and Structure” just doesn’t work.  The only way I found to do this while maintaining all the information is to copy it over programmatically.

In this example I created a drop down list of the the discussion boards on a site:

            foreach (SPList l in web.Lists)
            {
                if (l.BaseTemplate == SPListTemplateType.DiscussionBoard)
                {
                    ListItem entry = new ListItem();
                    entry.Text = l.Title;
                    entry.Value = web.Url + "/" + l.RootFolder;
                    ddl.Items.Add(entry);
                }
            }

Then I created a method to copy the discussion over once the source board, discussion, and destination board were set.

            string site = this.Page.Request.Url.ToString();
            using (SPSite spsSite = new SPSite(site))
            {
                using (SPWeb web = spsSite.OpenWeb())
                {
                    web.AllowUnsafeUpdates = true;

                    SPList splSource = web.GetList(ddlSourceList.SelectedItem.Value.ToString());
                    SPListItem spliDiscussion = web.GetListItem(ddlSourceDiscussion.SelectedItem.Value.ToString());
                    SPList splDestination = web.GetList(ddlDestinationList.SelectedItem.Value.ToString());

                    try
                    {
                        SPFolder fldrDiscussion = web.GetFolder(ddlSourceDiscussion.SelectedValue);
                        SPListItemCollection listCol = splDestination.Items;
                        SPListItem discussion = SPUtility.CreateNewDiscussion(listCol, spliDiscussion[SPBuiltInFieldId.Title].ToString());
                        discussion[SPBuiltInFieldId.Body] = spliDiscussion[SPBuiltInFieldId.Body];
                        discussion[SPBuiltInFieldId.Author] = spliDiscussion[SPBuiltInFieldId.Author];
                        discussion[SPBuiltInFieldId.Editor] = spliDiscussion[SPBuiltInFieldId.Editor];
                        discussion[SPBuiltInFieldId.Created] = spliDiscussion[SPBuiltInFieldId.Created];
                        discussion.Update();
                        CopyAttachments(spliDiscussion, discussion);
                        discussion.Update();
                        //copy replies
                        SPQuery q = new SPQuery();
                        q.Query = "<OrderBy><FieldRef Name='Title'/></OrderBy>";
                        q.Folder = fldrDiscussion;
                        SPListItemCollection flc = splSource.GetItems(q);
                        foreach (SPListItem li in flc)
                        {
                            SPListItem reply = SPUtility.CreateNewDiscussionReply(discussion);
                            reply[SPBuiltInFieldId.Body] = li[SPBuiltInFieldId.Body];
                            reply[SPBuiltInFieldId.Author] = li[SPBuiltInFieldId.Author];
                            reply[SPBuiltInFieldId.Editor] = li[SPBuiltInFieldId.Editor];
                            reply[SPBuiltInFieldId.Created] = li[SPBuiltInFieldId.Created];
                            reply.Update();
                            CopyAttachments(li, reply);
                            reply.Update();
                            discussion.Update();
                        }
                        //delete discussion
                        spliDiscussion.Delete();
                        this.Page.Response.Redirect(this.Page.Request.RawUrl);
                    }
                    catch { }
                    finally
                    {

                    }

                }
            }

Here is the method for copying the attachments over for the discussion as well:

        private void CopyAttachments(SPListItem spliDiscussion, SPListItem targetItem)
        {
            try
            {
                //get the folder with the attachments for the source item
                SPFolder fldrDiscAttachments = spliDiscussion.Web.Folders["Lists"].SubFolders[spliDiscussion.ParentList.Title].SubFolders["Attachments"].SubFolders[spliDiscussion.ID.ToString()];
                //Loop over the attachments, and add them to the target item
                foreach (SPFile file in fldrDiscAttachments.Files)
                {
                    byte[] binFile = file.OpenBinary();
                    targetItem.Attachments.AddNow(file.Name, binFile);
                }
            }
            catch { }
            finally
            {

            }
        }

There is one area where this is lacking, and that is the embedded content. (ie. if an image is attached, and then embedded with the full path URL, that will break, so you will either have to compensate for this in your code, or else just go into the posts and change the uploaded+embedded content manually.

Posted in SharePoint 2007.

4 Comments

  1. Where did you embed the code? Could I deploy the code in content Editor? I would save the script in the libary and then use the Content Editor under a Discussion Web Part. Would this work?

  2. Hi,

    When i try to move disuccussion reply,all posted by reply changes to the Person who is moving the discussion .

  3. I realize this was ages ago. So, I doubt this will be of any benefit to you, but I created a webpart wsp in C#, and put the code in there. I implemented it using some simple drop downs along with a submit button.

  4. Priyanka, I realize this was ages ago, so I doubt this will be of any use to you. However, I think you should be able to fetch the SPUser and assign it to the post. I have not tested this though.

Leave a Reply

Your email address will not be published. Required fields are marked *