OK. Я пытаюсь написать приемник событий, чтобы дать пользователю полный контроль над любым файлом, который он загружает. Я могу заставить код работать, пока я вошел в систему как администратор. Этот же код получает исключение System.UnauthorizedAccessException:> Access is denied. (Exception from HRESULT: x80070005E_ACCESSDENIED))
, когда я вхожу как участник и загружаю файл.
Я пробовал пару «решений» и другие различные способы решения проблемы, как видно из приведенного ниже комментария. Из того, что я прочитал, будет необходимо каким-то образом воссоздать объект, в то время как привилегии повышены, чтобы иметь эти привилегии для рассматриваемого объекта. Но ни один из методов не может найти предмет. Кажется, предмета еще нет в списке. О, и это библиотека документов.
//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
Итак, решение, которое работает в данный момент:
...
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();
...
}
}
});
...
У меня есть некоторые опасения относительно необходимости таймера, идея, которую я нашел откуда-то еще. Из того, что я видел, похоже, что ItemAdded запускается асинхронно, а поскольку необходим таймер (я пробовал без него), похоже, что CheckIn также асинхронный. Я действительно не знаю, почему он так себя ведет, но это моя гипотеза.