This is part of a series of posts about Working with Discussion lists programmatically: Part 1(This one), Part 2, Part 3.
I am currently involved in a project that requires a programmatic way to query a discussion list for it’s data, and create new items in it.
As it turns out, SharePoint discussion lists are not so ordinary lists. They have a very complex structure to store it’s data.
I came across several resources that helped me figure out how this whole thing works, and they are listed at the end of this post. This post is the summary of what I learned, and an more dated version that apply to SP 2010.
Before we get into code, lets try to understand how those lists are organized.
Content types
If you take a look at a discussion list’s settings page, you will see that it uses tow different content types: Discussion, and Message.
Discussion list’s content types
Discussions are new threads that are opened by users. I refer to them generally as Topics.
Messages are the responses posted at a topic. I refer to them generally as Replies.
If you follow the content types hierarchy, you will see that Topics are actually Folders.
So every topic you open, is in fact a folder, and the replies to that topic are list items stored in that folder.
Threading
So we know how topics are stored, and how to get to replies in them. Once we got the list of replies of a specific topic, how would we know which reply is for which?
Take this conversation for example:
If we will try to get all the reply for the topic “I have a question”’, we will get a flat list of all the replies. But what if we wanted to build a tree representation like it was originally? We need a way to tell for each reply object, what it was a reply for.
Here comes the threading attribute. Each reply has a hidden column called “Threading” (there are other columns as well that contains the same data).
This column stores a chained string that represent the depth of this item in the tree of replies. Each time we add a new reply down the tree, that reply get’s the parent reply’s threading string, appended with some other new string.
The threading value of messages
As you can see, the threading of the reply “I know the answer” has the same length of “The answer is 42”, because they are at the same level. But threading of “LOL” is a bit longer, because it was a reply to “The answer is 42”.
So to wrap it up:
Views
We now have the understanding for how to build something like the default views of a discussion list.
The default view for a discussion list shows all the topics.
Discussion list’s default view
To recreate this view we need to get the folders in the list.
Actually, folders are actually list items, so it’s sufficient to get the root level list items. Some times I will prefer this method.
The Flat view just shows all the replies for a selected topics without any indentation.
To recreate this view, we need to get all the items in the designated folder, and print them as a list.
The Threaded view also shows replies for a selected topic, but in a hieratical way that takes care of indentation.
Discussion list’s threaded view
To recreate this view, we need to get all the items in the designated folder. Once we have them we will sort the list based the threaded column. To add correct indentation, we can right-pad each item based on the length of the threaded value. Let take for example the first reply - “I know the answer”. It’s thread value is:
0x01CCB587E59C913F9BF0EB9145C79AD6606C8EA970CC000002F5D6 |
The length is 57. So we can add 57px of right padding(If you want smaller padding you can do some kind of calculation based on the length).
This will create the tree looking structure.
Summary
In this post we learned how SharePoint’s discussion lists work. We now have the tools to recreate the basic functionality of a discussion list. This is what I’m going to do in the following posts.
In the making of this post I have used the following posts.