在SPItemEventReceiver ItemAdded中,如何在贡献者时设置项目的更改权限?

时间:2011-02-01 17:57:34

标签: sharepoint sharepoint-2007 wss-3.0

行。我正在尝试编写一个事件接收器,以便用户完全控制他们上传的任何文件。只要我以管理员身份登录,我就能让代码工作。当我作为贡献者登录并上传文件时,相同的代码会出现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);
    }




更新


因此,目前正在使用的解决方案是:

        ...

        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也是异步的。我真的不知道为什么会这样,但那是我的假设。

2 个答案:

答案 0 :(得分:5)

可能,默认情况下会检出您上传的文件,因此即使在RunwithElevatedPrevileges块中也无法检索其ListItem。尝试这样做:

properties.ListItem.File.CheckIn(String.Empty);

在RunwithElevatedPrevileges阻止之前。

答案 1 :(得分:0)

您的应用程序池帐户似乎不是网站集管理员。执行RunwithElevatedPrevileges时,它基本上冒充应用程序池帐户。因此,请确保您已获得该帐户的许可。