一个文档库权限控制的eventhandler
最近在写一个文档库的eventhandler,目的是是操作人拥有对自己新建的文件夹(文件)完全控制的权限,这样该用户就可以完全控制属于自己的文件。一个简单的eventhandler,折磨了我1,2日的时间,为了以后防止这样的“低级”错误,所以要记下来。
注意红色代码部分,当前用户不一定拥有某些代码的执行权限,所以使用提升权限方法,尽量提升为管理员权限去执行。建议以下写法:
using (SPSite ElevatedSite = new SPSite(properties.SiteId))
{
using (SPWeb ElevatedWeb = ElevatedSite.OpenWeb(properties.OpenWeb().ID))
另外list.GetItemById方法和list.Items.GetItemById方法是有区别的,用list.Items.GetItemById的效率比较低,因为它会首先获取所有的item,所以建议尽量用list.GetItemById
SPListItem item = list.GetItemById(properties.ListItemId);
上代码:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace ******.EventHandle
{
//此类的作用就是用户上传文档的时候给用户完全对自己的文件完全控制的权限,这样就可以在文档库级别给用户添加的权限就行了
public class ControlMyDoc : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite ElevatedSite = new SPSite(properties.SiteId))
{
using (SPWeb ElevatedWeb = ElevatedSite.OpenWeb(properties.OpenWeb().ID))
{
try
{
ElevatedWeb.AllowUnsafeUpdates = true;
string SiteCollectionOwner = ElevatedSite.Owner.Name;
SPList list = ElevatedWeb.Lists[properties.ListId];
SPListItem item = list.GetItemById(properties.ListItemId);
//如果是基础父级权限,没独立出来权限的话就拷贝父级权限,然后脱离继承
if (!item.HasUniqueRoleAssignments)
{
item.BreakRoleInheritance(true);//取消权限继承,如果false去除所有权限,true复制所有权限并停止继承
}
else
{
//先重新继承上级权限,再去除所有权限重新分配
properties.ListItem.ResetRoleInheritance();
properties.ListItem.BreakRoleInheritance(true);
}
SPUser user = ElevatedWeb.Users.GetByID(properties.CurrentUserId);
SPRoleAssignment ra1 = new SPRoleAssignment(ElevatedWeb.EnsureUser(user.LoginName));
ra1.RoleDefinitionBindings.Add(ElevatedWeb.RoleDefinitions["完全控制"]);
item.RoleAssignments.Add(ra1);
//资料上说ItemUpdated会执行10次,用下面这个方法解决
this.DisableEventFiring();
item.Update();
this.EnableEventFiring();
}
catch
{
}
}
}
}
);
}
}
}
注意:后来发现,当文档库设置为需要签入、签出的时候,非管理员上传文档的时候,文档的权限并不能从父级剥离和继承权限,初步怀疑原因是整个操作都是以系统管理员身份进行的,但是系统管理员也并不能看到用户已上传但没签入的文档,就是说这一句的代码:SPListItem item = list.GetItemById(properties.ListItemId);里,item并不能获取到。至于怎么解决这个问题,目前还没想到。如果有想到的请告诉我一下,谢谢!