locked
how to add reply to Discusion List. RRS feed

  • Question

  • HI,

     

    i am handling discussion board through programming.

    i have retrive replies of individual topic of discussion board list.

     

    But i am not able to add new reply to a particular toic of a discussion board list. can any body help me, through some sample code.

     

    Thanks

     

    Monday, June 4, 2007 10:04 AM

Answers

  • Hi folks,

     

    I've found a solution for posting messages as reply with the correct formatting.

    You have to fill both the BODY field and the TRIMMEDBODY field with HTML-formatted content.

    Parts of the content (e.g. "Subject")  must be extracted from the original message before creating the reply
      (marked with colors in the example).

     

    With this trick, Sharepoint will do the magic behind and will add some Javascript code for the Show/Hide Message functionality.

     

    Regards,

    Axel

     

     

    Code example:

     

    SPListItem disc = SPUtility.CreateNewDiscussion(myListCol, "New message");

    disc["Body"] = "My new message content";

    disc.Update();

     

     

    SPListItem reply = SPUtility.CreateNewDiscussionReply(disc);

     

    reply["Body"] = "<div class=ExternalClass89C47CD7892B4279A8F42A65DD63AE3A><div> </div> <div>Reply to the new message<br><br> <hr> <b>From: </b>Admin<br><b>Posted: </b>Friday, July 20, 2007 4:01 AM<br><b>Subject: </b>New message<br><br> <div class=ExternalClass3D04672E599B486F9ECB76C138494708> <div>My new message content</div></div></div></div>";

     

     reply["TrimmedBody"] ="<div class=ExternalClass677134B4EA284660B1B236824800345C><div> </div> <div>Reply to the new message<br></div></div>";

               

    reply.Update();

     

     

    Tuesday, July 24, 2007 2:49 PM

All replies

  • You can use the method within SPUtility called CreateNewDiscussionReply().   Check the WSS 3.0 SDK for it's signature.

    To use the method, just iterate through the items within the Discussion Board using SPListItemCollection getting each SPListItem in turn until you find the message you want to reply to.  Call CreateNewDiscussionReply and pass in the item you want to reply to, you'll get back a new SPListItem that's a reply to the original message.  Just update the fields you need and call Update() to post the reply.

    BTW The threading of messages doesn't appear to be guaranteed using this function though - I'm having issues building the entire contents of a Discussion Board using this method and having SharePoint handle the threading correctly.

    Hope this helps,
    David.
    Monday, June 25, 2007 3:59 AM
  • Hi, I have the same trouble getting message threads right. Did you find a solution?

     

    I am trying to add Discussions and Replies to a Sharepoint Discussion Board via a custom webservice programmatically.

     

    SPListItem item = SPUtility.CreateNewDiscussion(list.Items, title);

     

    is used to add a new Discussion, and

     

    SPListItem item = SPUtility.CreateNewDiscussionReply(list.GetItemById(id));

     

    is used to add a reply on a Discussion.

    Till this point all goes well. Now to the problems. The look and feel is very different when I add it manually with the Internet Browser

    1.  Show / Hide Quoted Message option in the Browser is missing

    2.  From, Posted, Subject and the previous message are not in the Body

     

     

    When added programmatically, the show or hide quoted messages are missing and the body would be empty if the following command would not be executed.

     

    item ["Body"] = message;

    Message = „lets test this thing“;

     

    How can I get the body of the message to look just like the one that is created manually with the Internet Browser, and to have the Hide or Show option for all the replies.

     

    Another problem is that I connect to the webservice via a user credential cache. Lets assume that I cannot change my credential cache to another user, and I am forced to change the user info via the item[****] properties. What would be the best approche to do this programmatically?

     

    Thanx in advance…

    Axel

     

     

     

    Wednesday, July 18, 2007 9:45 AM
  • I'm sorry to say that the only workaround that works so far is to introduce a timeout between posting messages to the Discussion Board.  I'm not calling that a solution.

    I can examine the SPListItem object's properties once it's posted using CreateNewDiscussionReply() and the Threading field's value is incorrect.  Unfortunately this is a read-only field.

    I'm writing to the following fields:
    message["Subject"] - string
    message["Body"] - string
    message["Created"] - DateTime
    message["Modified"] - DateTime
    message["Created By"] - SPUser
    message["Modified By"] - SPUSer


    I've also got a few custom fields for other details and attachements.  No problems posting the data, just can't guarantee the threading. ;(

    David.

    Thursday, July 19, 2007 4:55 AM
  • Thanks for the information.

    Hope, the product group will fix this ;-)

     

    Best regards,

    Axel

     

    Thursday, July 19, 2007 1:22 PM
  • Hi folks,

     

    I've found a solution for posting messages as reply with the correct formatting.

    You have to fill both the BODY field and the TRIMMEDBODY field with HTML-formatted content.

    Parts of the content (e.g. "Subject")  must be extracted from the original message before creating the reply
      (marked with colors in the example).

     

    With this trick, Sharepoint will do the magic behind and will add some Javascript code for the Show/Hide Message functionality.

     

    Regards,

    Axel

     

     

    Code example:

     

    SPListItem disc = SPUtility.CreateNewDiscussion(myListCol, "New message");

    disc["Body"] = "My new message content";

    disc.Update();

     

     

    SPListItem reply = SPUtility.CreateNewDiscussionReply(disc);

     

    reply["Body"] = "<div class=ExternalClass89C47CD7892B4279A8F42A65DD63AE3A><div> </div> <div>Reply to the new message<br><br> <hr> <b>From: </b>Admin<br><b>Posted: </b>Friday, July 20, 2007 4:01 AM<br><b>Subject: </b>New message<br><br> <div class=ExternalClass3D04672E599B486F9ECB76C138494708> <div>My new message content</div></div></div></div>";

     

     reply["TrimmedBody"] ="<div class=ExternalClass677134B4EA284660B1B236824800345C><div> </div> <div>Reply to the new message<br></div></div>";

               

    reply.Update();

     

     

    Tuesday, July 24, 2007 2:49 PM
  • Does anyone know if there is a similar API to add replies using web services?
    Monday, November 12, 2007 7:00 PM
  • This actually can be done through SharePoint Web Services without custom services on the server using the AddDiscussionListItem method on the Lists web service. I have discovered several tricks for using this method. First of all, the message has to be MIME encoded, with the following header fields:
    Message-id
    Thread-index
    Subject
    Mime-version
    Content-type

    This MIME text needs to be converted into an array of bytes to call Lists.AddDiscussionBoardItem. The key to creating a reply is in the Thread-index message header. If the call is made a second time with the same thread index, the second call will create a reply to the topic created by the first call.

    It took me forever to figure this out. Doesn't anyone else out there use SharePoint Web Services?

    Ram
    Thursday, September 10, 2009 3:41 PM
  • Hi Ram,

    thank you very much for this encouraging message. I tried Lists.AddDiscussionBoardItem with MIME packed message with headers. It creates the first message in the discussion perfectly. But any time I use Thread-Index header, it fails with the exception "Invalid length for a Base-64 char array". The message seems reasonable but the same call without Thread-Index creates a new discussion thread pretty well. Did you have this error while you were trying this method? Maybe the list should be configured in some special way? How to avoid it to create a reply?

    Thank you very much, Mark
    Friday, September 11, 2009 1:13 PM
  • Mark,

    Here's an example of the code I'm using. This is very much a work in progress, because I'm still trying to figure out all the ins and outs. But this does work to create a discussion board topic and a reply to that topic. Note that I'm encoding only the thread index in Base64, because I found some obscure documentation that suggested it is expecting this. Maybe that's a piece that's missing for you:

     

    public void DiscussionAddTopic(string url, string listName, string topic)
    {
        _lists.Url = url +
    "/_vti_bin/Lists.asmx";

     

        string threadIndex = Base64Encoder.Encode("" + new Guid().ToString() + "@blahblahblah");

     

        string mime = "Message-ID: 99\n";
        mime +=
    "Thread-Index: " + threadIndex + "\n";
        mime +=
    "Subject: This is the topic\n";
        mime +=
    "Mime-Version: 1.0\n";
        mime +=
    "Content-type: text/plain; charset=us-ascii\n\n";
        mime +=
    "This is the body of the topic\n";

        byte
    [] bytes = new byte[mime.Length];
        for (int i = 0; i < mime.Length; i++)
            bytes[i] = (
    byte)mime[i];

        _lists.AddDiscussionBoardItem(listName, bytes);

     

        mime = "Message-ID: 100\n";
        mime +=
    "Thread-Index: " + threadIndex + "\n";
        mime +=
    "Subject: This is the reply\n";
        mime +=
    "Mime-Version: 1.0\n";
        mime +=
    "Content-type: text/plain; charset=us-ascii\n\n";
        mime +=
    "This is the body of the reply\n";

        bytes =

    new byte[mime.Length];
        for (int i = 0; i < mime.Length; i++)
            bytes[i] = (
    byte)mime[i];

        _lists.AddDiscussionBoardItem(listName, bytes);
    }

    By the way, if you know how to read and display the contents of a discussion board item, please let me know. That should be fairly simple but I haven't figured it out yet.


    Ram
    Saturday, September 12, 2009 8:58 PM
  • Hi Ram,

    Encoding Thread-Index is what I missed. Now I got reply added to the thread correctly! Thank you very much. It is a great progress. My very first message however looks like a reply itself, not like a first message as it would look like if it would be posted without Thread-Index at all. I am thinking about how to make it look like a main post. It is visible in the Threaded view of the discussion board.

    I read discussion boards using Lists.GetListIstems method. I use the query like this one:

    <Query><Where><Eq><FieldRef Name="ID"/><Value Type="Text">ITEM_ID</Value></Eq></Where></Query>

    The key is to specify field Body when retrieving the top level discussion group and to specify field Threading when reading replies. Threading allows to build reply tree because it contains information about the parent reply. All other fields will come by default, just take a look what comes from GetListItem call.

    Thank you,
    Mark
    Monday, September 14, 2009 3:48 PM
  • Mark,

    As I said, I haven't figured out the magic behind thread indices and replies yet. It may just be "bad magic", as the behavior in SharePoint itself is rather strange. I don't find that replies get put where you would expect them. That is, they don't get nested below the topic or reply to which you tried to add them. If I can figure out more about this I'll add something here.

    I did follow your suggestion to read the topics, and I can now do that ok. I don't quite follow how to get the replies, however. I'm using something like this:

     

    XmlDocument xmlDoc = new System.Xml.XmlDocument();
    XmlNode ndQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
    XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
    XmlNode ndQueryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");

    ndQuery.InnerXml =

    "<Where><Eq><FieldRef Name='ID'/><Value Type='Text'>" + topic.ID + "</Value></Eq></Where>";
    ndViewFields.InnerXml =
    "<FieldRef Name='Body' /><FieldRef Name='Threading' />";

     

    XmlNode nodes = _lists.GetListItems(listName, null, ndQuery, ndViewFields, null, ndQueryOptions, null);

     

    foreach (XmlNode item in nodes.SelectNodes("//*[local-name()='row']"))
    {
        string title = item.Attributes.GetNamedItem("ows_Title").Value;
        string body = item.Attributes.GetNamedItem("ows_Body").Value;
        string reply = item.Attributes.GetNamedItem("ows_Threading").Value;
    }

    The value for the reply is just a big number, I don't see the body of the reply anywhere in this. Obviously, I'm not doing it quite right. Could you possibly post an example of querying for the body of a reply?

    Ram


    Ram
    Monday, September 14, 2009 7:54 PM
  • Hi Ram,

    In a SharePoint discussion board discussion is like a folder and replies are like items in this folder (Discussion content type is inherited from folder and Message is inherited from Item). When I query replies I do it for the folder which is its discussion board. To do this, I use QueryOptions parameter on GetListItems. It may have Folder element which I set to something like http://host:port/site/boardname/folderid. This path (or part of it) can be retrieved from the topic (which is the folder) query and then it could be used to query replies. I think that when you will use QueryOptions with Folder you may even remove Where query by ID (but include Threading field) and all replies in this discussion groups will come in one query.

    I am sorry for not positing the code which is scattered around several classed and I do not have one single piece that does the job.

    Mark
    Tuesday, September 15, 2009 4:14 AM
  • Hi Ram,

    I am using the mime code to create new discussions, but this is what happening - if there is No discussion topic at all then the first topic creates successfully using this code, but if i try it second time the code execute without any error but no topic is created. Any ideas Why?

    let me know if you need more details.

    Thanks,

    Richa

    Wednesday, July 18, 2012 7:02 PM
  • Hi Ram / Mark,

    I am facing the issue of reply not getting associated to correct topic even after encoding the thread index. I used Convert.ToByte64String(byte[]) method of .Net instead of Base64Encoder class. If i need to use the same Base64Encoder class then can you please send me that class.

    Is something i am missing here. Please find my code below.

                byte[] ItemGUIDbytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Guid.NewGuid().ToString() + "@abc");
                string threadIndex = Convert.ToBase64String(ItemGUIDbytes);
                //For body
    
                string mime = "Message-ID: 99\n";
                mime += "Thread-Index: " + threadIndex + "\n";
                mime += "Subject: This is the new topic\n";
                mime += "Mime-Version: 1.0\n";
                mime += "Content-type: text/plain; charset=us-ascii\n\n";
                mime += "This is the body of the topic\n";
    
                byte[] bytes = new byte[mime.Length];
    
                for (int i = 0; i < mime.Length; i++)
                    bytes[i] = (byte)mime[i];
    
           srvTargetLists2010.AddDiscussionBoardItem("{EEA3339E-B31A-41AF-9DFE-49D35CC0F4F7}", bytes);
    
                //For reply
    
                mime = "Message-ID: 100\n";
                mime += "Thread-Index: " + threadIndex + "\n";
                mime += "Subject: This is the new reply\n";
                mime += "Mime-Version: 1.0\n";
                mime += "Content-type: text/plain; charset=us-ascii\n\n";
                mime += "This is the body of the reply\n";
    
                bytes = new byte[mime.Length];
    
                for (int i = 0; i < mime.Length; i++)
                    bytes[i] = (byte)mime[i];
    
          srvTargetLists2010.AddDiscussionBoardItem("{EEA3339E-B31A-41AF-9DFE-49D35CC0F4F7}", bytes);

    Waiting for yor reply.

    Thanks,

    Sairam



    Sairam Avacorp Technologies

    • Proposed as answer by Sairams Wednesday, November 14, 2012 11:15 AM
    • Unproposed as answer by Sairams Wednesday, November 14, 2012 11:15 AM
    Tuesday, November 6, 2012 1:45 PM
  • I found the solution for my problem.


    Sairam Avacorp Technologies

    • Proposed as answer by Sairams Wednesday, November 14, 2012 11:16 AM
    • Unproposed as answer by Sairams Wednesday, November 14, 2012 11:16 AM
    Wednesday, November 14, 2012 11:16 AM