设置项目权限

13

文件夹操作:

我现在知道如何在库中设置文件夹的权限:

public void ChangeItemPermissions()
{
    _SharePoint.ClientContext _ClientContext = new _SharePoint.ClientContext("https://sharepoint.oshirowanen.com/sites/oshirodev/");
    _ClientContext.Credentials = new NetworkCredential("user", "pass", "oshirowanen.com");

    _SharePoint.Principal user = _ClientContext.Web.EnsureUser(@"oshirowanen\tom");

    var _List = _ClientContext.Web.Lists.GetByTitle("Library1");
    var _Item = _List.LoadItemByUrl("/sites/oshirodev/Library1/Folder1");
    var roleDefinition = _ClientContext.Site.RootWeb.RoleDefinitions.GetByType(_SharePoint.RoleType.Reader);
    var roleBindings = new _SharePoint.RoleDefinitionBindingCollection(_ClientContext) { roleDefinition };
    _Item.BreakRoleInheritance(false,true);
    _Item.RoleAssignments.Add(user, roleBindings);

    _ClientContext.ExecuteQuery();
}

尝试添加文件:

我尝试在这行中加入文件名:

var _Item = _List.LoadItemByUrl("/sites/oshirodev/Library1/Folder1/File1.docx");

注意,(/File1.docx)已添加到上面的行末。


接收到的错误信息:

但是,这只会产生一个错误:

System.NullReferenceException was unhandled
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=ItemPermissions
  StackTrace:
       at ItemPermissions.Form1.ChangeItemPermissions() in c:\Users\Oshirowanen\Documents\Visual Studio 2013\Projects\ItemPermissions\ItemPermissions\Form1.cs:line 46
       at ItemPermissions.Form1.button1_Click(Object sender, EventArgs e) in c:\Users\Oshirowanen\Documents\Visual Studio 2013\Projects\ItemPermissions\ItemPermissions\Form1.cs:line 345
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at ItemPermissions.Program.Main() in c:\Users\Oshirowanen\Documents\Visual Studio 2013\Projects\ItemPermissions\ItemPermissions\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

相关信息:

这是一个使用C#创建的WinForm应用程序,运行在本地机器上,使用.NET 4.0。SharePoint版本为2010。


问题:

如何设置特定文件的权限?因为我已经知道如何为特定文件夹设置权限。


5个回答

4
我查看了2010 CSOM文档,发现您正在使用的LoadItemByUrl方法不存在。那是您编写的扩展吗,也许是这个?如果是,那么问题可能出在该扩展中,可能是CAML查询的问题。
作为参考,此2010 CSOM代码可对SharePoint 2010实验室正常工作。请注意,它使用GetItemByID:
        ClientContext _ClientContext = new ClientContext("http://team/sites/Team1/");
        _ClientContext.Credentials = new NetworkCredential("administrator", "*****", "corp");
        Principal user = _ClientContext.Web.EnsureUser(@"corp\administrator");
        var _List = _ClientContext.Web.Lists.GetByTitle("Shared Documents");
        var _Item = _List.GetItemById(23);
        var roleDefinition = _ClientContext.Site.RootWeb.RoleDefinitions.GetByType(RoleType.Reader);
        var roleBindings = new RoleDefinitionBindingCollection(_ClientContext) { roleDefinition };
        _Item.BreakRoleInheritance(false, true);
        _Item.RoleAssignments.Add(user, roleBindings);
        _ClientContext.ExecuteQuery();

很不幸,由于意外情况,上周我无法使用电脑。如何指定文件而不是使用GetItemById? - oshirowanen

2

我认为andresm53提到的扩展方法是正确的。

为了让这个方法在文件上工作,您需要通过FileLeafRef(文件名)进行查询,并确保将FileLeafRef添加到查询的ViewFields中。

/edit

还有一件非常重要的事情,使用以下方式将文件查询限制为精确文件夹:

query.FolderServerRelativeUrl = System.IO.Path.GetDirectoryName(url).Replace("\\", "/");

以下是可行的代码:

以下是可行的代码:

void Main()
{
    ClientContext context = new ClientContext("https://sharepoint.oshirowanen.com/sites/oshirodev/");
    context.Credentials = new NetworkCredential("user", "pass", "oshirowanen.com");
    Principal user = context.Web.EnsureUser(@"oshirowanen\tom");
    ChangeItemPermissions(context, "/sites/oshirodev/Library1/Folder1/File1.docx", "Library1", user, RoleType.Reader);
}

// Define other methods and classes here
public static ListItem LoadItemByUrl(List list, string url)
{
    var context = list.Context;
    string ext = System.IO.Path.GetExtension(url);

    var query = new CamlQuery();
    if (string.IsNullOrEmpty(ext))
        query.ViewXml = String.Format("<View><RowLimit>1</RowLimit><Query><Where><Eq><FieldRef Name='FileRef'/><Value> Type='Url'>{0}</Value></Eq></Where></Query></View>", url);
    else
    {
        query.ViewXml = String.Format("<View><ViewFields><FieldRef Name=\"FileLeafRef\" /></ViewFields><Query><Where><Eq><FieldRef Name=\"FileLeafRef\" /><Value Type=\"Text\">{0}</Value></Eq></Where></Query><RowLimit>1</RowLimit></View>", System.IO.Path.GetFileName(url));
        query.FolderServerRelativeUrl = System.IO.Path.GetDirectoryName(url).Replace("\\", "/");
    }

    var items = list.GetItems(query);
    context.Load(items);
    context.ExecuteQuery();
    return items.Count > 0 ? items[0] : null;
}

public void ChangeItemPermissions(ClientContext context, string url, string listName, Principal user, RoleType type)
{    
    var list = context.Web.Lists.GetByTitle(listName);
    var item = LoadItemByUrl(list, url);
    var roleDefinition = context.Site.RootWeb.RoleDefinitions.GetByType(type);
    var roleBindings = new RoleDefinitionBindingCollection(context) { roleDefinition };
    item.BreakRoleInheritance(false, true);
    item.RoleAssignments.Add(user, roleBindings);
    context.ExecuteQuery();
}

由于上周意外地无法使用电脑,我无法接受答案,因此为了这个答案再次添加了悬赏。这个答案非常好用。感谢您的帮助! - oshirowanen

1

你的上下文中没有加载任何内容。你需要使用“查询”来加载你的上下文以执行,如果在没有加载的情况下执行,它将不会做任何事情。这可能需要一些细微的更改,但概念是正确的。

var _List = _ClientContext.Web.Lists.GetByTitle("Library1");
var _Item = _List.LoadItemByUrl("/sites/oshirodev/Library1/Folder1");
_ClientContext.Load(_Item);
_ClientContenxt.ExecuteQuery(); 

var roleDefinition = _ClientContext.Site.RootWeb.RoleDefinitions.GetByType(_SharePoint.RoleType.Reader);
_ClientContext.Load(roleDefinition);
_ClientContenxt.ExecuteQuery();

var roleBindings = new _SharePoint.RoleDefinitionBindingCollection(_ClientContext) { roleDefinition };
_Item.BreakRoleInheritance(false,true);
_Item.RoleAssignments.Add(user, roleBindings);

_ClientContext.Load(_Item);
_ClientContext.ExecuteQuery();

我刚刚尝试了一下,但是如果我包括 File1.docx,我仍然会收到相同的错误消息。 - oshirowanen
这有帮助吗?http://www.morgantechspace.com/2016/04/set-list-item-level-permission-using-csom-c-sharp.html - andresm53
@andresm53,我之前尝试过那段代码,但我认为它是针对较新版本的SharePoint。它给了我两个错误:“无法转换lambda表达式”和“不包含SiteUsers的定义”。我正在使用SharePoint 2010。 - oshirowanen

0

我猜你的问题与你使用的路径有关:

 _Item = _List.LoadItemByUrl("/sites/oshirodev/Library1/Folder1/File1.docx");

试试这个

 Uri filename = new Uri(@"http://server//oshirodev/Library1/Folder1/File1.docx");

 string server = filename.AbsoluteUri.Replace(filename.AbsolutePath, "");

 Microsoft.SharePoint.Client.ClientContext clientContext = new Microsoft.SharePoint.Client.ClientContext(server);

_ClientContext.Credentials = new NetworkCredential("user", "pass", "oshirowanen.com");

_SharePoint.Principal user = _ClientContext.Web.EnsureUser(@"oshirowanen\tom");

var roleDefinition = _ClientContext.Site.RootWeb.RoleDefinitions.GetByType(_SharePoint.RoleType.Reader);
var roleBindings = new _SharePoint.RoleDefinitionBindingCollection(_ClientContext) { roleDefinition };
_Item.BreakRoleInheritance(false,true);
_Item.RoleAssignments.Add(user, roleBindings);

_ClientContext.ExecuteQuery();

0

试试这个。

 static void Main()
        {
            string siteUrl = "Your site url";
            ClientContext clientContext = new ClientContext(siteUrl);

            var list = clientContext.Web.Lists.GetByTitle("JZhu");
            var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
            clientContext.Load(items);
            clientContext.ExecuteQuery();

            clientContext.Load(clientContext.Web.SiteGroups);
            clientContext.ExecuteQuery();

            GroupCollection oSiteCollectionGroups= clientContext.Web.SiteGroups;
            foreach (Group grp in oSiteCollectionGroups)
            {
                Console.WriteLine(grp.Title);
                if (grp.Title == "My group")
                {
                    oGroup=gpr;
                    break;
                }
            }

            foreach (var item in items)
            {
                var folder = GetListItemFolder(item); //get Folder
                Console.WriteLine(folder.Name);
                if (folder.Name=="Folder 1" || folder.Name=="Folder 2")
                {
                    item.BreakRoleInheritance(false);
                    RoleDefinitionBindingCollection collRoleDefinitionBinding = new RoleDefinitionBindingCollection(clientContext);

                    //set role type
                    collRoleDefinitionBinding.Add(clientContext.Web.RoleDefinitions.GetByType(RoleType.Reader));
                    //oGroup - your group
                    item.RoleAssignments.Add(oGroup, collRoleDefinitionBinding);

                    clientContext.ExecuteQuery();
                }
            }
        }

        private static Folder GetListItemFolder(ListItem listItem)
        {
            var folderUrl = (string)listItem["FileDirRef"];
            var parentFolder = listItem.ParentList.ParentWeb.GetFolderByServerRelativeUrl(folderUrl);
            listItem.Context.Load(parentFolder);
            listItem.Context.ExecuteQuery();
            return parentFolder;
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接