OK. I am trying to write an event receiver to give a user full control of any file that they upload. I can get the code to work so long as I'm logged in as Administrator. The same code gets an System.UnauthorizedAccessException:> Access is denied. (Exception from HRESULT: x80070005E_ACCESSDENIED))
exception when I login as a contributor and upload a file.
I have tried a couple 'solutions' and various other things to solve the problem as seen in commented code below. From what I've read, it will be necessary to somehow recreate the object while privileges are elevated in order to have those privileges on the object in question. But neither of the methods is able to find the item. It seems the item is not yet in the list. Oh, and this is a Document Library.
//Works as admin
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);//tried putting this at top and bottom of method, thinking perhaps this where the file get put in list.
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (var site = new SPSite(properties.SiteId))
using (var web = site.OpenWeb(properties.RelativeWebUrl))
{
...
//works when admin
var item = properties.ListItem;
//attempt: by item url
//this does not work, file not found
var item = web.GetListItem(properties.ListItem.Url);
//attempt: by item ID
// this works
var list = web.Lists[properties.ListId];
//this does not
var item = list.GetItemById(properties.ListItemId);
item.BreakRoleInheritance(true); //this get the access denied error
item.RoleAssignments.Add(GetRoleAssignment(web, item));
...
}
}
base.ItemAdded(properties);
}
UPDATE
So, the solution that is currently working is:
...
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (var site = new SPSite(properties.SiteId))
using (var web = site.OpenWeb(properties.RelativeWebUrl))
{
try
{
properties.ListItem.File.CheckIn(String.Empty);
System.Threading.Thread.Sleep(1000);
var list = web.Lists[properties.ListId];
var item = list.Items[properties.ListItem.UniqueId];
item.BreakRoleInheritance(true);
item.RoleAssignments.Add(GetRoleAssignment(web, item));
}
catch (Exception e)
{
LogError(e.ToString());
}
finally
{
properties.ListItem.File.CheckOut();
...
}
}
});
...
I have some apprehension concerning the necessity of the timer, the idea for which I gleaned from elsewhere. From what I've seen, it appears that ItemAdded is fired asynchronously, and since the timer is necessary (I tried it without), it seems CheckIn is also asynchronous. I really don't know why it is behaving as such, but that is my hypothesis.
Possible, the file you are uploading is checked out by default, so even in RunwithElevatedPrevileges block you cannot retrieve its ListItem. Try do this:
just before RunwithElevatedPrevileges block.