I am trying to create an app that will set item level security for certain items in a library. However, I am getting the error mentioned above after these lines:

item.RoleAssignments.Add( grp, roleDefBinding );

I found this question on Stack Overflow, and tried to copy the code, with some changes. Here is the full code:

var spContext = SharePointContextProvider.Current.GetSharePointContext( Context );
using ( var ctx = spContext.CreateUserClientContextForSPHost() )
    Web w = ctx.Web;
    ctx.Load( w, web=> web.SiteGroups, web=>web.RoleDefinitions );

    List list = w.Lists.GetById( Guid.Parse( ddlLibraries.SelectedItem.Value ) );

        roleNameStr = ddlPermissions.SelectedItem.Text,
        grpName = ddlBUs.SelectedItem.Text;

    var role = w.RoleDefinitions.Where( r => r.Name == roleNameStr );
    if ( role.Count() > 0 )
        RoleDefinition roleDef = role.First();
        var group = w.SiteGroups.Where( g => g.Title == grpName );
        if ( group.Count() > 0 )
            RoleDefinitionBindingCollection roleDefBinding = new RoleDefinitionBindingCollection( ctx );
            roleDefBinding.Add( roleDef );

            Group grp = group.First() as Group;

            CamlQuery query;
            query = CamlQuery.CreateAllItemsQuery();

            Microsoft.SharePoint.Client.ListItemCollection items = list.GetItems( query );
            ctx.Load( items );

            foreach ( Microsoft.SharePoint.Client.ListItem item in items )
                ctx.Load( item, i=>i.RoleAssignments, i=>i.HasUniqueRoleAssignments );
                if ( !item.HasUniqueRoleAssignments )
                    item.BreakRoleInheritance( true, false );
                item.RoleAssignments.Add( grp, roleDefBinding );

Are there any errors in my code, or something I am missing? Not sure if it makes a difference, but this is an Office 365 environment.

Thank you in advance.


It might be the ExecuteQuery you call right after you create RoleDefinitionBindingCollection.

This code should work:

static void BreakInheritanceAndSetRoleAssignmentByGroupOnItems(ClientContext clientContext, 
    Web web, string roleName, string groupTitle, List<ListItem> items)
    var role = web.RoleDefinitions.FirstOrDefault(r => r.Name == roleName);
    if (role == null) return;

    var group = web.SiteGroups.FirstOrDefault(g => g.Title == groupTitle);
    if (group == null) return;

    var roleDefBinding = new RoleDefinitionBindingCollection(clientContext) {role};

    items.ForEach(item =>
        if (!item.HasUniqueRoleAssignments)
            item.BreakRoleInheritance(true, false);
        item.RoleAssignments.Add(group, roleDefBinding);

Note that it does not call ExecuteQuery at all, which is a good thing. But it also expects your Web to contain the correct values, as well as items.
Example usage:

var web = ctx.Web;
var items = web.Lists.GetByTitle("Test").GetItems(CamlQuery.CreateAllItemsQuery());
ctx.Load(items, collection => collection.Include(item => item.HasUniqueRoleAssignments));
ctx.Load(web, w=> w.SiteGroups.Include(sg => sg.Title), w=> w.RoleDefinitions.Include(rd => rd.Name));


const string roleName = "Edit"; 
const string groupName = "MyGroup"; 

BreakInheritanceAndSetRoleAssignmentByGroupOnItems(ctx, web, roleName, groupName, items.ToList());
  • Note that this will not remove the existing permissions. If you want to do that you could do something like item => item.RoleAssignments when loading items and then calling item.RoleAssignments.ToList().ForEach(ra => ra.DeleteObject()); where you call BreakRoleInheritance
    – eirikb
    Apr 30 '14 at 6:07
  • This worked. I'm still new to CSOM, and still a bit confused when to call ClientContext.ExecuteQuery(). Thank you.
    – wjervis
    Apr 30 '14 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.