Threaded Discussion using SharePoint 2007 Web Services

There have been a few comments lately on this post I made a while back on how the threaded discussion works.  Their question revolves around working with the SharePoint threaded discussion via web services, and more specifically how to post a response to thread or a response to a response.  I was going to work through that this week in my spare time, but as luck would have it someone internally posted how to do this.  I can’t take credit for it, but was given permission by the author, Srinivas Rao Choudam, to post it to share with the greater community.

As I suspected before getting into this it requires calling two methods in the Lists.asmx web service, AddDiscussionBoardItem and UpdateListItems.  The code for making this happen is shown below.

   1: ListsSoapClient client = new ListsSoapClient("ListsSoap");
   2: client.ClientCredentials.Windows.ClientCredential = (System.Net.NetworkCredential)System.Net.CredentialCache.DefaultCredentials;
   3: client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
   6: XmlNamespaceManager manager = null;
   7: XmlElement discussionItem = null;
   9: manager = new XmlNamespaceManager(new NameTable());
  10: manager.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
  11: manager.AddNamespace("z", "#RowsetSchema");
  13: StringBuilder mesBody = new StringBuilder(1024);
  15: mesBody.AppendFormat("Message-ID: {0}\n", Guid.NewGuid().ToString());
  17: mesBody.AppendFormat("Subject: {0}\n", "Discussion112");
  19: mesBody.Append("Mime-Version: 1.0\n");
  21: mesBody.Append("Content-type: text/plain; charset=UTF-8\n\n");
  23: discussionItem = client.AddDiscussionBoardItem("TeamDiscussion", Encoding.UTF8.GetBytes(mesBody.ToString()));
  25: XmlNode discussionNode = discussionItem.SelectSingleNode("rs:data/z:row", manager);
  27: string serverUrl = discussionNode.Attributes["ows_ServerUrl"].InnerText;
  28: string fileLeafRef = discussionNode.Attributes["ows_FileLeafRef"].InnerText;
  31: XmlDocument xmlDocument = new XmlDocument();
  32: XmlElement updatesNode = xmlDocument.CreateElement("Batch");
  33: updatesNode.SetAttribute("RootFolder", serverUrl);
  34: updatesNode.SetAttribute("OnError", "Continue");
  36: XmlElement methodNode = xmlDocument.CreateElement("Method");
  37: methodNode.SetAttribute("ID", "0");
  38: methodNode.SetAttribute("Cmd", "New");
  39: updatesNode.AppendChild(methodNode);
  42: XmlElement bodyNode = xmlDocument.CreateElement("Field");
  43: bodyNode.SetAttribute("Name", "Body");
  44: bodyNode.InnerText = "Body-New";
  45: methodNode.AppendChild(bodyNode);
  47: XmlElement contentTypeNode = xmlDocument.CreateElement("Field");
  48: contentTypeNode.SetAttribute("Name", "ContentType");
  49: contentTypeNode.InnerText = "Message";
  50: methodNode.AppendChild(contentTypeNode);
  53: XmlElement fileLeafRefNode = xmlDocument.CreateElement("Field");
  54: fileLeafRefNode.SetAttribute("Name", "DiscussionTitleLookup");
  55: fileLeafRefNode.InnerText = fileLeafRef;
  56: methodNode.AppendChild(fileLeafRefNode);
  58: discussionItem = client.UpdateListItems("TeamDiscussion", updatesNode);
Comments (5)
  1. John says:

    First off, thanks Cliff and Srinivas.

    I divided the code into 2 segments and perhaps I shouldn’t have. I can’t run the first part to call AddDiscussionBoardItem and I’m wondering if it has something to do with the ThreadIndex not being included in the MIME?

    If I run the 2nd segment using the Serverl_Url and FileLeafRef from an existing top level Discussion I receive a sucess; however, all the responses I create get added as a top level Discussion instead of a reply Message. It looks like they should be reply Messages though as they have no Subject and the Threading is indented by one level.

    Any thoughts would be most appreciated!


  2. Jen Etzler says:

    I got this to work with a couple modifications. First, you need to include the thread-index in the message header in order to handle the replies correctly. All subsequent items with the same thread-index will be placed in the discussion as replies. Next, you want to append the body and trimmed body after the header. You don't want to use client.updatelistitems method because this changes the thread modified date, and if the modified date doesn't match the created date, you won't get the Show/Hide Quoted Messages link. Code follows. I have this as a function that receives the ListName, one discussion or message item as an XmlNode, and the discussion title. Using this, we don't need any of the XmlDocument code or the batch update.

    String trimmedBody = itemNode.Attributes.GetNamedItem("ows_BodyAndMore").Value;

    String threadIndex = itemNode.Attributes.GetNamedItem("ows_ThreadIndex").Value;

     StringBuilder mesBody = new StringBuilder(1024);

                   mesBody.AppendFormat("Message-ID: {0}n", Guid.NewGuid().ToString());

                   mesBody.AppendFormat("Thread-Index: {0}n", base64Encode(threadIndex));

                   mesBody.AppendFormat("Subject: {0}n", title); //the ows_Title of the discussion – messages don't always have titles…

                   mesBody.Append("Mime-Version: 1.0n");

                   mesBody.Append("Content-type: text/html; charset=UTF-8nn");



                   discussionItem = client.AddDiscussionBoardItem(ListName, Encoding.UTF8.GetBytes(mesBody.ToString()));

  3. gabouy says:

    Hi Cliff, thanks for your post, but I have an issue with the pieces of code shared here.

    If I try the the code provided by Srinivas in WSS 3, it works, but items are not bound as replies. The reply counter shows cero, and they are not indented in the threaded view.

    On the other hand if I try the approach suggested by Jen Etzler, the base64Encode for threadIndex such as 0x01CD0A10BC91224453E8DFE44A989B1A124ABCB8EBD5 fails. I really need to get this working can anyone offer some assistance here?

    thanks in advance

  4. wayne alston says:

    i have the same problem.. i need to be able to generate an email with Thread-Index value using the same value as ows_ThreadIndex but cannot get it into a suitable format..



  5. Srinivasan Venkatesan says:

    Thank you guys..

Comments are closed.

Skip to main content