Working with Comments on SharePoint 2019 Modern Pages

With SharePoint 2019 we get new Modern Pages. With Modern Pages we get completely renewed Comments feature which looks like that example on image above.

On SharePoint 2019 you could currently use only Comments without Like and Views feature as on SharePoint Online (image below).

There is a new Comment REST API from where you could read / write comments for specific page and it is available on SharePoint 2019 and SharePoint Online. More about that you could read in that blog post from @vrdmn.

What I want to show you today is how you could programmatically read this comments from SharePoint SSOM.

So, lets start.

You have to connect to your SharePoint 2019 site firstly:

using (SPSite site = new SPSite("http://sp2019"))
	using (SPWeb web = site.OpenWeb())

After that (inside of this two using statements) you have to connect to your Site Pages Library where you have one of your SharePoint Modern Page with some comments already posted (in my case is page with ID 5):

SPList list = web.Lists.TryGetList("Site Pages");
SPListItem li = list.GetItemById(5);

You could get number of comments from “_CommentCount” list item property:


But if you want to get each of comments it will take a lil’bit of hacking.
In code below you could see my solution for that problem with Reflection.

Firstly we have to load Microsoft.SharePoint.dll assembly from SharePoint Hive Directory.

We have to use CommentQuery type for creating query to retrieve Modern Page comments.
Inside of this query we want to use default sort type with GetDefaultSortType from CommentsUtils.

After that we want to set IncludeNumberOfRepliesInCount property of CommentQuery to true.

Then we have to use CommentEntitySet constructor for retrieving comments from our list item (variable li) with commentQuery defined before.

We get back list of Comments (CommentEntity type) from which we want to get next properties:

  • Author
  • Created
  • Text
Assembly ass = Assembly.LoadFile(@"C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.dll");

Type tCommentsUtils = ass.GetType("Microsoft.SharePoint.Comments.CommentsUtils");
MethodInfo mGetDefaultSortType = tCommentsUtils.GetMethod("GetDefaultSortType", BindingFlags.NonPublic | BindingFlags.Static);
var sortType = mGetDefaultSortType.Invoke(null, new object[] { li });

Type tCommentQuery = ass.GetType("Microsoft.SharePoint.Comments.CommentQuery");
ConstructorInfo ciCommentQuery = tCommentQuery.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[1];
var commentQuery = ciCommentQuery.Invoke(new object[] { null, sortType });

PropertyInfo piIncludeNumberOfRepliesInCount = tCommentQuery.GetProperty("IncludeNumberOfRepliesInCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

piIncludeNumberOfRepliesInCount.SetValue(commentQuery, true);

Type tCommentEntitySet = ass.GetType("Microsoft.SharePoint.Comments.CommentEntitySet");
ConstructorInfo ciCommentEntitySet = tCommentEntitySet.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];

dynamic comments = ciCommentEntitySet.Invoke(new object[] { li, commentQuery });

Type commentEntity = ass.GetType("Microsoft.SharePoint.Comments.CommentEntity");
PropertyInfo piAuthor = commentEntity.GetProperty("Author", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PropertyInfo piCreatedDate = commentEntity.GetProperty("CreatedDate", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PropertyInfo piText = commentEntity.GetProperty("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

Type principal = ass.GetType("Microsoft.SharePoint.Sharing.Principal");
PropertyInfo piName = principal.GetProperty("Name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

foreach (dynamic comment in comments)
	Console.WriteLine("Author: " + piName.GetValue(piAuthor.GetValue(comment)));
	Console.WriteLine("Created: " + piCreatedDate.GetValue(comment));
	Console.WriteLine("Text: " + piText.GetValue(comment));

Happy coding folks!

Gašper Rupnik


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by

Up ↑

%d bloggers like this: