【问题标题】:Set Item Permissions设置项目权限
【发布时间】:2017-10-23 14:57:05
【问题描述】:

文件夹工作:

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

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: 

相关信息:

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


问题:

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

【问题讨论】:

    标签: c# .net sharepoint sharepoint-2010 csom


    【解决方案1】:

    我查看了2010 CSOM documentation,您使用的 LoadItemByUrl 方法不存在。那是你写的扩展,也许是this one?如果是这样,那么问题一定出在那个扩展中,可能在 CAML query 中。

    作为参考,此 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?
    【解决方案2】:

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

    要使此方法适用于您需要通过FileLeafRef(文件名)查询的文件,并确保将FileLeafRef 添加到查询ViewFields

    /编辑

    还有一件非常重要的事情,将文件查询限制为精确的文件夹:

    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();
    }
    

    【讨论】:

    • 为这个答案增加了更多的赏金,因为上周我因意外无法访问计算机而无法接受答案。这个答案很好用。感谢您的帮助!
    【解决方案3】:

    您没有在上下文中加载任何内容。您需要使用“查询”加载您的上下文才能执行,如果您在不加载的情况下执行,它不会做任何事情。这可能需要稍作改动,但这个概念是正确的。

    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,我仍然会收到相同的错误消息。
    • 这有帮助吗? morgantechspace.com/2016/04/…
    • @andresm53,我之前尝试过该代码,但我认为它适用于较新版本的共享点。它给了我 2 个错误 cannot convert lambda pxpressiondoes not contain a definition for SiteUsers。我正在使用 SharePoint 2010。
    【解决方案4】:

    试试这个。

     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;
            }
    

    【讨论】:

      【解决方案5】:

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

       _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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-15
        • 2021-05-30
        • 1970-01-01
        • 2012-01-27
        • 2012-08-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多