Search code examples
c#.netc#-4.0sharepoint-2010.net-4.0

Set Folder Permissions


I have the following code which works fine when creating folders:

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

    var _web = _ClientContext._web;
    var _Root = _web.Lists.GetByTitle("Library1");
    var _folder1 = _Root.RootFolder.Folders.Add("Folder1");
    var _subfolder1 = _folder1.Folders.Add("SubFolder1");
    _folder1.Update();
    _subfolder1.Update();

    var _folder2 = _Root.RootFolder.Folders.Add("Folder2");
    var _subfolder2 = _folder2.Folders.Add("SubFolder2");
    _folder1.Update();
    _subfolder1.Update();

    _ClientContext.ExecuteQuery();
}

I understand how to change the permissions of everything within a library for example:

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

    _SharePoint.Principal _user = _ClientContext.Web.EnsureUser(@"oshiro\tom");
    _SharePoint.List _item = _ClientContext.Web.Lists.GetByTitle("Library1");
    var roleDefinition = _ClientContext.Site.RootWeb.RoleDefinitions.GetByType(_SharePoint.RoleType.Reader);  //get Reader role
    var roleBindings = new _SharePoint.RoleDefinitionBindingCollection(_ClientContext) { roleDefinition };
    _item.BreakRoleInheritance(true, false);
    _item.RoleAssignments.Add(_user, roleBindings);
    _ClientContext.ExecuteQuery();
}

But I don't want to change the permissions for everything, I only want to set the permissions for the new folders I am creating.

So I tried this:

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

    _SharePoint.Principal _user = _ClientContext.Web.EnsureUser(@"oshiro\tom");
    _SharePoint.Folder _folder = _ClientContext.Web.GetFolderByServerRelativeUrl("/sites/oshirodev/Library1/Folder1");

    var roleDefinition = _ClientContext.Site.RootWeb.RoleDefinitions.GetByType(_SharePoint.RoleType.Reader);
    var roleBindings = new _SharePoint.RoleDefinitionBindingCollection(_ClientContext) { roleDefinition };

    _folder.ListItemAllFields.BreakRoleInheritance(true, false);
    _folder.ListItemAllFields.RoleAssignments.Add(user, roleBindings);

    _ClientContext.ExecuteQuery();
}

But this code does not work in SharePoint 2010 because ListItemAllFields was not introduced to SharePoint until Sharepoint 2013.

My question is, how do I set permissions for these folders so only a specific user has access to them? Ideally, if this can be set while creating the folders, that would be great. If that is not possible, then settings the permissions after creating the folders will be fine.

The application is a WinForm.


Solution

  • As you said since ListItemAllFields that would allow you to give permissions to a specific user was only introduced in SharePoint 2013, you can't leverage it.

    If you checkout this answer however, you can see that there is a way around it, by installing this plugin and create your own ListExtensions class, since it would still not be exposed.

    static class ListExtensions
    {
        /// <summary>
        /// Load List Item by Url 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static ListItem LoadItemByUrl(this List list, string url)
        {
            var context = list.Context;
            var query = new CamlQuery
            {
                ViewXml = String.Format("<View><RowLimit>1</RowLimit><Query><Where><Eq><FieldRef Name='FileRef'/><Value> Type='Url'>{0}</Value></Eq></Where></Query></View>", url),
            };
            var items = list.GetItems(query);
            context.Load(items);
            context.ExecuteQuery();
            return items.Count > 0 ? items[0] : null;
        }
    }
    

    Where the CamlQuery is the most critical part of it, and would allow you to update the permissions by using something like

    public void ChangeFldPerms2()
    {
        SharePoint.ClientContext _ClientContext = new _SharePoint.ClientContext("https://sharepoint.oshiro.com/sites/oshirodev/");
        _ClientContext.Credentials = new NetworkCredential("user", "pass", "oshiro.com");
        _SharePoint.Principal _user = _ClientContext.Web.EnsureUser(@"oshiro\tom");
    
        var list = _ClientContext.Web.Lists.GetByTitle("Library1");
        var folderItem = list.LoadItemByUrl("/sites/oshirodev/Library1/Folder1");
        var roleDefinition = _ClientContext.Site.RootWeb.RoleDefinitions.GetByType(_SharePoint.RoleType.Reader);
        var roleBindings = new _SharePoint.RoleDefinitionBindingCollection(_ClientContext) { roleDefinition };
        folderItem.BreakRoleInheritance(true, false);
        folderItem.RoleAssignments.Add(user, roleBindings);
    
        _ClientContext.ExecuteQuery();
    }