Today with new issue and its solution 🙂
Error: Cannot add a role assignment with empty role definition binding collection.
TrackTrace : atMicrosoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream) at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse() at Microsoft.SharePoint.Client.ClientContextExtensions.ExecuteQueryImplementation(ClientRuntimeContext clientContext, Int32 retryCount, Int32 delay, String userAgent)
Scenario: We are now working for a migration project and we need to migrate a SharePoint 2010 site to office 365 SharePoint online site. We are implementing a tool using CSOM, which will do all magic for us.
As per the requirement we need to migrate all permissions granted for webs, lists and items as well. After finished with our code we start running our tool with a test site. And the tool run successfully with few minor issues. When we test the migrated site, we found that the destination migrated site was quite similar to the source site, except migration of permissions for example, if there are certain groups and user has permission on 2010 source site but not available on migrated sites and when we manually try to grant permission to those groups and user it works.
Now we try to debug the code to find out the actual issue.
After debugging the code, we found that, the issue comes up, when it tries to add a new role assignment to the role assignment collection as in following Figure 1.
Figure 1: Office 365 – CSOM code – adding new role assignment to role assignment collection
As the error message (Cannot add a role assignment with empty role definition binding collection.) it seems our role assignment binding collection is empty but as we can see in following Figure 2 that our binding collection is not empty and our principal also not null.
Figure 2: Office 365: CSOM – debugging code – quickwatch
Cause of the Issue:
To add a new role assignment, following steps are required
- Get our required Principal
- Get our RoleDefinitionBindingCollection
- Add new Role Assignment to role assignment collection by passing the above element as Add method’s parameters.
Here as per the concept, all the above three steps should go with one query, I mean to say it should be done with one context.Executequery(). But if we see our code, we are sending multiple queries to achieve our goal as shown in following figure 3.
Figure 3: Office 365: CSOM – debugging code – with multiple query
Here the simple fix for this issue is, to remove Query 1 and Query 2 and everything will be handle by the last Query 3. Now it should work as per the concept. But still we are getting the same issue even after removing the extra ctx.ExecuteQueryRetry().
The reason behind this, In middle of this task, we are calling a method GetGroupID(pID), to get the correct Group id and in that method, we are using same context and sending different query by calling ctx.ExecuteQueryRetry(). This is actually breaking the chain and here as per the requirement, we can’t avoid this code with extra query.
We have addressed this issue by reordering our code a little. If we see the above code, we are getting the Principal object after getting RoleDefinitionBindingCollection .To fix the issue we just swap the place of both objects. We first get Principal object and then work for RoleDefinitionBindingCollection. Addition to this code reordering we need extra ctx.ExecuteQueryRetry() For each as shown in following figure 4 and it works for us.
Figure 4: Office 365 – CSOM – Corrected Code
Hope this helps you and will save time 🙂
Keep reading, share your thoughts, experiences. Feel free to contact us to discuss more. If you have any suggestion / feedback / doubt, you are most welcome.
Stay tuned on Knowledge-Junction, will come up with more such articles.
Thanks for reading 🙂