While performing list item updates programmatically, you try to elevate the permissions or trying to impersonate or Brake the role inheritance, you get the following error. You will not get this error if you are logged in as an admin. Only contributor users face this error.
Error in the log:
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) at Microsoft.SharePoint.SPGlobal.HandleUnauthorizedAccessException(UnauthorizedAccessException ex) at Microsoft.SharePoint.Library.SPRequest.UpdateRoleAssignment(String bstrUrl, Guid& pguidScopeId, Int32 lPrincipalID, Object& pvarArrIdRolesToAdd, Object& pvarArrIdRolesToRemove) at Microsoft.SharePoint.SPRoleAssignmentCollection.UpdateAssignment(Int32 principalId, SPRoleDefinitionBindingCollection bindings, Boolean addOnly) at Microsoft.SharePoint.SPRoleAssignmentCollection.Add(SPRoleAssignment roleAssignment) at MYDLL.MYDLLHandler.ItemAdded(SPItemEventProperties properties)
Use "Allow unsafe updates=true" After each and every code line. You MUST use this statement before and after the "BreakRoleInheritance" line. Ofcrs Make it false only once, while leaving the whole code.
That should fix the issue, if you are still facing the problem, follow the below one by one. Any one of the solutions should fix your problem.
- Believe me, I spent countless hours to get this simple solution.
Code the SPSite and SPWeb instances after the RunWithElevatedPrivileges(delegate() line. But initiate the context before the code line.
Always go with Ids instead of site or webs, if you are facing the problems even after this solution.
Guid MywebGuid = SPContext.Current.Web.ID;
Guid MysiteGuid = SPContext.Current.Site.ID;
//RunWithElevatedPrivileges(delegate() code block
SPSite MySite = new SPSite(MysiteGuid)
Keep in your mind that all the site context declarations/assignments (Guid MysiteGuid = SPContext.Current.Site.ID) should be made before the RunWithElevatedPrivileges(delegate() line. Coz, even though the user is elevated with the full control permissins using the RunWithElevatedPrivileges(delegate() line, if you declare/assign the values after the code line, while assigning the context values, control switches back to the contributor access.
But, where as if you declare/assign the values before the code line, context will be initiated as the contributor first and then enters in the code block as the full control user with the context carried over. So no issues.
- Use IDs instead of ListItems.This makes sure, not to reuse an object that was created in the context of a non-administrative user
Guid listID = properties.ListId;
Guid listItemID = properties.ListItemId;
SPListItem listItem = web.Lists[listID].GetItemById(listItemID);
- If this list is a document library, make sure you have the file checked-in before the "RunWithElevatedPrivileges" line or else check out the list item to the system account.
In the case of Admin login, you were the admin and was going through the system checkout by default:
Also check on the application pool id being the same as the elevated.
- Disable all the events being fired.