I recently was tasked to import a legacy discussion board into SharePoint 2010. So I wrote a small application, that could dump the old discussions to XML and then import them into SharePoint 2010 using the SharePoint Object model. Nothing more easy than this. A discussion-board is just some kind of list after all.
Well, kinda. If you look closely, you will notice, that discussion-boards differ in some details from regular lists. For one: a discussion-board has threads and replies. The replies can be shown threaded, so I have to maintain which post is a reply to what other post.
SharePoint does some strange stuff to manage this. Each discussion thread is a folder. With this knowledge one might expect to find all replies in this folder, which sound total reasonable to me. But that’s not the SharePoint way. Instead all replies are siblings. Folders are just the SharePoint-way to distinguish threads from replies. I don’t really know how SharePoint manages the reply-hierarchy, but it does work – somehow.
Well, after these discoveries, let’s write some code. I assume the new discussion board already exists and all there is to do is to import the existing posts from the old forum. First I have to create a new thread like this:
var newThread = SPUtility.CreateNewDiscussion(discussionBoard.Items, oldPost.Title);
newThread[SPBuiltInFieldId.Body] = oldPost.Text;
newThread[SPBuiltInFieldId.Created] = FormatDate(oldPost.Date);
string author = CheckUser(oldPost.Creator, web);
newThread[SPBuiltInFieldId.Author] = author;
newThread[SPBuiltInFieldId.Editor] = author;
newThread.Update();
Then I check the oldPost
for replies and append them to my newly created thread.
foreach (var oldReply in oldPost.Replies)
{
var newReply = SPUtility.CreateNewDiscussionReply(newThread);
string replyAuthor = CheckUser(oldReply.Creator, web);
newReply[SPBuiltInFieldId.Body] = oldReply.Text;
newReply[SPBuiltInFieldId.Created] = FormatDate(oldReply.Date);
newReply[SPBuiltInFieldId.Author] = replyAuthor ;
newReply[SPBuiltInFieldId.Editor] = replyAuthor ;
newReply[SPBuiltInFieldId.Title] = oldReply.Title;
newReply.Update();
newThread.Update();
}
The replies can be created recursively for replies to replies as well.
This is actually all that is needed. So with some little magic of the SPUtility
namespace I was able to import a couple of thousand messages in no time.