Even after breaking permission inheritance, you can't directly change a user's permissions to Read -- you technically have to remove their existing permissions, then Add the Read permission.
First, even though you only want to grant a single permission (i.e.
Read), you still need to construct a
RoleDefinitionBindingCollection to hold that one RoleDefinition, because the
RoleAssignmentCollection.Add only accepts a collection.
Then you have to loop through the existing
RoleAssignments on the item to get a collection of users/groups (
Principals) who already are assigned to the item. If you are certain that all items already inherit from the parent, you could just do this once and get the collection of
Principals before you being the loop, which would be more efficient, but could miss any users already assigned through broken inheritance.
Then, when you call
BreakRoleInheritance, use the
false parameter that wipes out the permissions on the item instead of copying the existing. Then, finally you can loop through the collection of
Principals you already have and create
Reader Role Assignments for each
Principal on the item.
RoleDefinition readerDef = ctx.Web.RoleDefinitions.GetByType(RoleType.Reader);
RoleDefinitionBindingCollection readOnlyBinding = new RoleDefinitionBindingCollection(clientContext);
foreach (ListItem i in collListItem)
List<Principal> usersToGrantRead = new List<Principal>();
foreach (RoleAssignment r in i.RoleAssignments)
i.BreakRoleInheritance(false,false); // false clears out all permissions on the item
foreach (Principal p in usersToGrantRead)