Wednesday, 12 October 2016

SharePoint 2013 (CSOM): Star Ratings Programmatically Adding Star-Rating or Re-Rating a List Item.

This Blog is about SharePoint's Star Rating Feature and how to change/read the Field Values Programmatically using CSOM. That is basically Rating or Re-rating the item.

What can be done by the following code is :
  • Select a list (should have ratings enabled).
  • Select the Item form the list.
  • Select a Site user whom you need to rate.
  • Finally the main code
    • To change the user's rating.
              OR
    • To rate the item.
  • To view the field values.

Most of the aspects of Star Rating are being covered but how Un-rate is intentionally not being covered as the user cant un-rate the item in SharePoint out of the box. If you want a code to un-rate the item please comment about it, I would Post it later.  
Note: Please use it for Ethically.
Code:
1. Console apps main Program code.
                 
class RatingsMain
{
static void Main(string[] args)
{
ClientContext clientContext = new ClientContext("http://Your Site url ");
SecureString password = new SecureString();
foreach (char c in "Your Password ".ToCharArray())
password.AppendChar(c);
clientContext.Credentials = new NetworkCredential("User Name", password, "Domain Name");
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
Console.Title = "Ratings";
FetchList getList = new FetchList();
List list = getList.ByName(clientContext, web);
Console.Title = "Ratings:" + list.Title;
FetchItem getItem = new FetchItem();
ListItem item = getItem.ByName(clientContext, list);
Console.Title = "Ratings:" + list.Title + ">" + item.DisplayName;
SetUser getUser = new SetUser();
User user = getUser.ByName(clientContext, list, item);
Console.Title = "Ratings:" + list.Title + ">" + item.DisplayName + " (" + user.Title + ")";
ChangeRating reCalculate = new ChangeRating();
reCalculate.NewRatings(clientContext, list, item, user);
list.Update();
clientContext.ExecuteQuery();
Console.ReadLine();
clientContext.Dispose();
}
}
view raw RatingsMain.cs hosted with ❤ by GitHub
2. Code of the FetchList Class.
                
class FetchList
{
public List ByName(ClientContext clientContext, Web web)
{
clientContext.Load(web.Lists, l => l.IncludeWithDefaultProperties(i => i.Title));
clientContext.ExecuteQuery();
List list = web.Lists[0];
int numberOfTries = 5;
bool isListPresent = false;
string listName;
Console.WriteLine("Site: " + web.Title);
Console.WriteLine();
Console.WriteLine("Enter the List Name To Select");
string skipReadingListName = Console.ReadLine();
do
{
numberOfTries--;
if (skipReadingListName == "" || numberOfTries == 0)
return DefaultList(clientContext);
listName = skipReadingListName;
//a function to ensure the list is present in current web.
CustomListCheck(clientContext, listName, out list, out isListPresent);
if (!isListPresent)
{
Console.Clear();
Console.WriteLine("Site: " + web.Title);
Console.WriteLine();
Console.WriteLine("The List name is miss-spelled!\nOr\nList with name '" + listName + "' is not Present!.\nPlease re-enter the List Name/Title\nOr\nPress EnterKey to skip and use DefaultList");
skipReadingListName = Console.ReadLine();
}
} while (!isListPresent);
clientContext.Load(list);
clientContext.ExecuteQuery();
return list;
}
//function to select a default list.
private List DefaultList(ClientContext clientContext)
{
//alert user that default list is being selected.
Console.WriteLine("List name skipped hence default list 'TestingList' is being selected\n Do you wish to continue Y/N");
string reselect = Console.ReadLine();
if (reselect != "Y" && reselect != "y" && reselect != "")
ByName(clientContext, clientContext.Web);
List defaultList = clientContext.Web.Lists.GetByTitle("TestingList");
clientContext.Load(defaultList);
clientContext.ExecuteQuery();
return defaultList;
}
//function to check whether list with listName specified is present or not and return with the list.
private void CustomListCheck(ClientContext clientContext, string listName, out List customList, out bool isPresent)
{
isPresent = false;
clientContext.Load(clientContext.Web.Lists);
clientContext.ExecuteQuery();
ListCollection lists = clientContext.Web.Lists;
clientContext.Load(lists);
clientContext.Load(lists, t => t.IncludeWithDefaultProperties(l => l.Title));
clientContext.ExecuteQuery();
customList = lists[0];
foreach (List list in lists)
if (list.Title == listName)
{
customList = clientContext.Web.Lists.GetByTitle(listName);
isPresent = true;
break;
}
}
}
view raw FetchList.cs hosted with ❤ by GitHub
3. Code of FetchItem class.
                
class FetchItem
{
string itemName;
int numberOfTries = 5;
public ListItem ByName(ClientContext clientContext, List list)
{
Console.Clear();
Console.WriteLine("Site: " + clientContext.Web.Title);
Console.WriteLine("List: " + list.Title);
Console.WriteLine();
Console.WriteLine("Enter The Name of Item which you need to Rate");
string skipReadingItemName = Console.ReadLine();
ListItem item = list.GetItemById(1);
bool isItemPresent = false;
CamlQuery query = CamlQuery.CreateAllItemsQuery();
ListItemCollection items = list.GetItems(query);
clientContext.Load(items, i => i.IncludeWithDefaultProperties(t => t.DisplayName));
clientContext.ExecuteQuery();
do
{
numberOfTries--;
if (skipReadingItemName == "" || numberOfTries == 0)
return DefaultItem(clientContext, list);
itemName = skipReadingItemName;
foreach (ListItem itemCheck in items)
if (itemCheck.DisplayName == itemName)
{
item = itemCheck;
isItemPresent = true;
break;
}
if (!isItemPresent)
{
Console.Clear();
Console.WriteLine("Site: " + clientContext.Web.Title);
Console.WriteLine("List: " + list.Title);
Console.WriteLine();
Console.WriteLine("The Item name Provided is either miss-spelled or does not exists\nPlease re-enter the Item Name/DisplayName");
skipReadingItemName = Console.ReadLine();
}
} while (!isItemPresent);
clientContext.Load(item);
clientContext.ExecuteQuery();
return item;
}
//function to get default item.
private ListItem DefaultItem(ClientContext clientContext, List list)
{
ListItemCollection items = list.GetItems(CamlQuery.CreateAllItemsQuery());
clientContext.Load(items, i => i.IncludeWithDefaultProperties(t => t.DisplayName));
clientContext.ExecuteQuery();
ListItem defaultItem = items[0];
clientContext.Load(defaultItem);
clientContext.ExecuteQuery();
//alert the default item is being selected.
Console.WriteLine("Item name skipped hence Default item i.e. first item in list\n'" + defaultItem.DisplayName + "' is being selected\n Do you wish to continue Y/N");
string reselect = Console.ReadLine();
if (reselect != "y" && reselect != "Y" && reselect != "")
ByName(clientContext, list);
return defaultItem;
}
}
view raw FetchItem.cs hosted with ❤ by GitHub
4. Code of SetUser class.
               
class SetUser
{
public User ByName(ClientContext clientContext, List list, ListItem item)
{
clientContext.Load(clientContext.Web.SiteUsers, i => i.IncludeWithDefaultProperties(u => u.Title, u => u.Id));
clientContext.ExecuteQuery();
User user = clientContext.Web.SiteUsers.GetById(1);
bool isUserPresent = false;
int numberOfTries = 5;
string userName;
Console.Clear();
Console.WriteLine("Site: " + clientContext.Web.Title);
Console.WriteLine("List: " + list.Title);
Console.WriteLine("Item: " + item.DisplayName);
Console.WriteLine();
Console.WriteLine("Enter the User name");
string skipReadingUserName = Console.ReadLine();
do
{
if (skipReadingUserName == "" || numberOfTries == 0)
return DefaultUser(clientContext, list, item);
userName = skipReadingUserName;
numberOfTries--;
foreach (User userSearch in clientContext.Web.SiteUsers)
if (userSearch.Title == userName)
{ //if site-user with exact name is present.
user = userSearch;
isUserPresent = true;
break;
}
else if (userSearch.Title.Split(' ')[0] == userName)
{ //if site-user with FirstName is equal to the specified name is present.
user = userSearch;
isUserPresent = true;
}
if (!isUserPresent)
{
Console.Clear();
Console.WriteLine("Site: " + clientContext.Web.Title);
Console.WriteLine("List: " + list.Title);
Console.WriteLine("Item: " + item.DisplayName);
Console.WriteLine();
Console.WriteLine("The User name is miss-spelled \nOr\n User does not exists.\nPlease re-enter the User Name/Title");
string skipReadingItemName = Console.ReadLine();
}
} while (!isUserPresent);
clientContext.Load(user);
clientContext.ExecuteQuery();
return user;
}
//function to get default user.
private User DefaultUser(ClientContext clientContext, List list, ListItem item)
{
Console.WriteLine("User selection skipped hence default user user1 is being selected\n Do you wish to continue Y/N");
string reselect = Console.ReadLine();
if (reselect != "Y" && reselect != "y" && reselect != "")
return ByName(clientContext, list, item);
else
{
string loginName = "i:0#.w|sharepoint\\user1";
User defaultUser = clientContext.Web.EnsureUser(loginName);
clientContext.Load(defaultUser);
clientContext.ExecuteQuery();
return defaultUser;
}
}
}
view raw SetUser.cs hosted with ❤ by GitHub
5.  Code to change the ratings packed in ChangeRating class.
                
class ChangeRating
{
bool hasUserRated = false;
Random random = new Random();
int sumOfRatings = 0;
int userRatingIndex = 0;
int numberOfTries = 5;
float newAverageRating = 0;
int numberOfRatings = 0;
string newRatingsFromUser = string.Empty;
string newRatings = string.Empty;
List<FieldUserValue> newUsersRated = new List<FieldUserValue>();
public void NewRatings(ClientContext clientContext, List list, ListItem item, User user)
{
Console.Clear();
Console.WriteLine("Site: " + clientContext.Web.Title);
Console.WriteLine("List: " + list.Title);
Console.WriteLine("Item: " + item.DisplayName);
Console.WriteLine("User: " + user.Title);
Console.WriteLine();
FieldUserValue[] ratedUsers = item["RatedBy"] as FieldUserValue[];
if (ratedUsers != null)
for (int i = 0; i < ratedUsers.Length; i++)
if (ratedUsers[i].LookupValue == user.Title)
{
userRatingIndex = i;
hasUserRated = true;
break;
}
if (hasUserRated)
Rerate(item, user);
else
Rate(item, user, ratedUsers);
Console.WriteLine("Users Rating " + newRatingsFromUser + ",\n Ratings= " + newRatings + "\n Ratings Count= " + numberOfRatings + ",\n Average Ratings= " + newAverageRating);
item.Update();
}
//function to re-rate or skip rating the item
private void Rerate(ListItem item, User user)
{
int randomStarRating = random.Next(1, 5);
string[] ratings = item["Ratings"].ToString().Split(',');
numberOfRatings = int.Parse(item["RatingCount"].ToString());
string ratedValue = ratings[userRatingIndex];
Console.WriteLine("The User " + user.Title + " has already Rated the item with " + ratedValue + " star Rating\n Do you want to enter new Rating Y/N");
string reRate = Console.ReadLine();
if (reRate == "y" || reRate == "Y" || reRate == "yes" || reRate == "Yes")
{
for (int i = 0; i < numberOfRatings; i++)
if (i == userRatingIndex)
{
Console.WriteLine("Enter the new Star Rating or skip(EnterKey) to generate Random Star Rating");
string skipReadingRatings = Console.ReadLine();
do
{
if (skipReadingRatings == "" || numberOfTries == 1)
{
newRatingsFromUser = randomStarRating.ToString();
newRatings += newRatingsFromUser + ",";
sumOfRatings += randomStarRating;
}
else
{
newRatingsFromUser = skipReadingRatings;
if (newRatingsFromUser == "1" || newRatingsFromUser == "2" || newRatingsFromUser == "3" || newRatingsFromUser == "4" || newRatingsFromUser == "5")
{
newRatings += newRatingsFromUser + ",";
sumOfRatings += int.Parse(newRatingsFromUser);
}
else
{
Console.WriteLine("The ratings entered is incorrect please enter numbers from 1 to 5 only\nOr\n skip(EnterKey) to generate Random Star Rating");
skipReadingRatings = Console.ReadLine();
}
}
numberOfTries--;
} while (newRatingsFromUser != "1" && newRatingsFromUser != "2" && newRatingsFromUser != "3" && newRatingsFromUser != "4" && newRatingsFromUser != "5" && skipReadingRatings != "" && numberOfTries != 0);
}
else
{
newRatings += ratings[i] + ",";
sumOfRatings += int.Parse(ratings[i].ToString());
}
item["Ratings"] = newRatings;
item["AverageRating"] = (float)(sumOfRatings / numberOfRatings);
}
else
{
newRatingsFromUser = ratedValue;
newRatings = item["Ratings"].ToString();
newAverageRating = float.Parse(item["AverageRating"].ToString());
}
}
//Function To rate the item
private void Rate(ListItem item, User user, FieldUserValue[] ratedUsers)
{
int randomStarRating = random.Next(1, 5);
string[] ratings = item["Ratings"] != null ? item["Ratings"].ToString().Split(',') : null;
newRatings = item["Ratings"] != null ? item["Ratings"].ToString() : string.Empty;
newAverageRating = item["AverageRating"] == null ? 0 : float.Parse(item["AverageRating"].ToString());
numberOfRatings = item["RatingCount"] == null ? 0 : int.Parse(item["RatingCount"].ToString());
Console.WriteLine("The User " + user.Title + " has not Rated the item.\n Enter the new Star Rating or skip(EnterKey) to generate Random Star Rating");
string skip = Console.ReadLine();
do
{
if (skip == "" || numberOfTries == 1)
{
newRatingsFromUser = randomStarRating.ToString();
newRatings += newRatingsFromUser + ",";
newAverageRating = ((newAverageRating * numberOfRatings) + randomStarRating) / (numberOfRatings + 1);
//or
//newAverageRating = newAverageRating + ((randomStarRating - newAverageRating) / (numberOfRatings + 1));
}
else
{
newRatingsFromUser = skip;
if (newRatingsFromUser == "1" || newRatingsFromUser == "2" || newRatingsFromUser == "3" || newRatingsFromUser == "4" || newRatingsFromUser == "5")
{
newRatings += newRatingsFromUser + ",";
sumOfRatings += int.Parse(newRatingsFromUser);
newAverageRating = ((newAverageRating * numberOfRatings) + int.Parse(newRatingsFromUser)) / (numberOfRatings + 1);
}
else
{
Console.WriteLine("The ratings entered is incorrect please enter numbers from 1 to 5 only or skip(EnterKey) to generate Random Star Rating");
skip = Console.ReadLine();
}
}
numberOfTries--;
} while (newRatingsFromUser != "1" && newRatingsFromUser != "2" && newRatingsFromUser != "3" && newRatingsFromUser != "4" && newRatingsFromUser != "5" && skip != ""&& numberOfTries != 0);
numberOfRatings += 1;
item["RatingCount"] = numberOfRatings.ToString();
item["Ratings"] = newRatings;
item["AverageRating"] = newAverageRating.ToString();
if (ratedUsers != null)
foreach (FieldUserValue ratedUser in ratedUsers)
newUsersRated.Add(ratedUser);
newUsersRated.Add(FieldUserValue.FromUser(user.LoginName));
item["RatedBy"] = newUsersRated;
}
}
view raw ChangeRating.cs hosted with ❤ by GitHub
Please feel free to comment on any related issues.