简体   繁体   中英

Set Item Permissions

Folders work:

I now know how to set the permissions of a folder in a library:

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

File attempt:

I've tried adding the file name to this line:

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

Notice the ( /File1.docx ) added to the end of the above line.


Error received:

But that just gives an error:

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: 

Relevant info:

This is a WinForm app running on a local machine, created with C#, using .NET 4.0. SharePoint version is 2010.


The question:

How do I set the permissions for a specific file ? As I already know how to set permissions for a specific folder .

I reviewed the 2010 CSOM documentation , and the method you are using LoadItemByUrl doesn't exist. Is that an extension you wrote, perhaps this one ? If so then the problem must be in that extension, probably in the CAML query .

As a reference, this 2010 CSOM code worked ok against a SharePoint 2010 lab. Note that it uses 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();

I assume that andresm53 is right about you using the extension method he mentioned.

To get this method to work on files you need to query by FileLeafRef (file name) and make sure that you add FileLeafRef to query ViewFields .

/edit

One more very important thing, limit file query to exact folder with:

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

Working code below:

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

You aren't loading anything in your context. You need to Load your context with "queries" to execute, if you execute withou loading, it doesn't do anything. This may need some slight changes, but the concept is correct.

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

Try this.

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

I guess your problem is related to the path you're using:

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

Try this

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM