SharePoint 2010: Manage (Create/Delete/Rename) list folders with Client Object Model (OM)

SharePoint 2010 Client Object models allows almost everything to do from client side with Client OM. In this post I’ll show how to Add, remove and rename SharePoint list folders with Client OM. I have been using Managed client OM. However you can get the idea of how to use this code from Client OM for silverlight and Client OM for ECMAScript. Also the code snippet I have posted here in this post is will only work for list folders. However by changing few parts you can make it working for library.

Create or Add Folder

The following code snippet shows how to add a new folder in a list.
public void CreateFolder(string siteUrl, string listName, string relativePath, string folderName)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        Web web = clientContext.Web;
        List list = web.Lists.GetByTitle(listName);

        ListItemCreationInformation newItem = new ListItemCreationInformation();
        newItem.UnderlyingObjectType = FileSystemObjectType.Folder;
        newItem.FolderUrl = siteUrl + "/lists/" + listName;
        if (!relativePath.Equals(string.Empty))
        {
            newItem.FolderUrl += "/" + relativePath;
        }
        newItem.LeafName = folderName;
        ListItem item = list.AddItem(newItem);
        item.Update();
        clientContext.ExecuteQuery();
    }
}
As shown in the code snippet above, to add a folder with Client OM you need to create an instance of ListItemCreationInformation and set it’sUnderlyingObjectType to Folder. You can also set the path where to create the folder by setting the FolderUrl property value.
You can call the CreateFolder method as shown below which will create a folder ‘myfolder’ in the list ‘mylist’. As relative path is passed empty, the folder will be added in the root folder of the list.
helper.CreateFolder("http://server", "mylist", "", "myfolder");
However you can add folder in any subfolder of the list. For example the following code snippet will add the folder ‘mysubfolder’ in the list ‘mylist’ under the folder ‘myfolder’.
helper.CreateFolder("http://server", "mylist", "myfolder", "mysubfolder");

 

Delete or Remove folder

To delete folder with Client OM, you need to query the folder first. You can do so by using instantiate a CamlQuery object and executing it. The following code snippet shows how to delete folder.
public void DeleteFolder(string siteUrl, string listName, string relativePath, string folderName)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        Web web = clientContext.Web;
        List list = web.Lists.GetByTitle(listName);

        CamlQuery query = new CamlQuery();
        query.ViewXml = "<View Scope=\"RecursiveAll\"> " +
                        "<Query>" +
                            "<Where>" +
                                "<And>" +
                                    "<Eq>" +
                                        "<FieldRef Name=\"FSObjType\" />" +
                                        "<Value Type=\"Integer\">1</Value>" +
                                     "</Eq>" +
                                      "<Eq>" +
                                        "<FieldRef Name=\"Title\"/>" +
                                        "<Value Type=\"Text\">" + folderName + "</Value>" +
                                      "</Eq>" +
                                "</And>" +
                             "</Where>" +
                        "</Query>" +
                        "</View>";

        if (relativePath.Equals(string.Empty))
        {
            query.FolderServerRelativeUrl = "/lists/" + listName;
        }
        else
        {
            query.FolderServerRelativeUrl = "/lists/" + listName + "/" + relativePath;
        }

        var folders = list.GetItems(query);

        clientContext.Load(list);
        clientContext.Load(folders);
        clientContext.ExecuteQuery();
        if (folders.Count == 1)
        {
            folders[0].DeleteObject();
            clientContext.ExecuteQuery();
        }
    }
}
As shown in the above code snippet, I first instantiated the CamlQuery with the query to search the folder. The only trick to search folder only is to use the following part in the CAML query. If you want to use files only then use value 0 instead of 1.
<FieldRef Name="FSObjType" />
<Value Type="Integer">1</Value>
However you can use “CamlQuery.CreateAllFoldersQuery()” to get the query to search all folders. After preparing the CAML query you need to execute this against the list. For optimization you can specify the field names you want to load inside the Load method.

Rename Folder

To rename folder you need to get the folder item first. To get the folder you need to query the list for folder as shown in section “Delete or Remove Folder”. The following code snippet shows how to rename folder.
public void RenameFolder(string siteUrl, string listName, string relativePath, string folderName,string folderNewName)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        Web web = clientContext.Web;
        List list = web.Lists.GetByTitle(listName);

        string FolderFullPath = GetFullPath(listName, relativePath, folderName);

        CamlQuery query = new CamlQuery();
        query.ViewXml = "<View Scope=\"RecursiveAll\"> " +
                        "<Query>" +
                            "<Where>" +
                                "<And>" +
                                    "<Eq>" +
                                        "<FieldRef Name=\"FSObjType\" />" +
                                        "<Value Type=\"Integer\">1</Value>" +
                                     "</Eq>" +
                                      "<Eq>" +
                                        "<FieldRef Name=\"Title\"/>" +
                                        "<Value Type=\"Text\">" + folderName + "</Value>" +
                                      "</Eq>" +
                                "</And>" +
                             "</Where>" +
                        "</Query>" +
                        "</View>";

        if (relativePath.Equals(string.Empty))
        {
            query.FolderServerRelativeUrl = "/lists/" + listName;
        }
        else
        {
            query.FolderServerRelativeUrl = "/lists/" + listName + "/" + relativePath;
        }
        var folders = list.GetItems(query);

        clientContext.Load(list);
        clientContext.Load(list.Fields);
        clientContext.Load(folders, fs => fs.Include(fi => fi["Title"],
            fi => fi["DisplayName"],
            fi => fi["FileLeafRef"]));
        clientContext.ExecuteQuery();

        if (folders.Count == 1)
        {

            folders[0]["Title"] = folderNewName;
            folders[0]["FileLeafRef"] = folderNewName;
            folders[0].Update();
            clientContext.ExecuteQuery();
        }
    }
}
As shown in the code snippet above, I have specified the field names (Title, DisplayName, FileLeafRef) in the load method to ensure that these fields are populated on the client side. Once the query is executed by invoking the ClientContext.ExecuteQuery, the folders are populated. To rename folder you need to modify at least two properties (Title, FileLeafRef). Finally you need to call the update method and to send the change back to the server need to invoke the ExecuteQuery method

Search Folder

You can enumerate a list for folders as shown below:
public void SearchFolder(string siteUrl, string listName, string relativePath)
{
    using (ClientContext clientContext = new ClientContext(siteUrl))
    {
        Web web = clientContext.Web;
        List list = web.Lists.GetByTitle(listName);

        string FolderFullPath = null;

        CamlQuery query = CamlQuery.CreateAllFoldersQuery();

        if (relativePath.Equals(string.Empty))
        {
            FolderFullPath = "/lists/" + listName;
        }
        else
        {
            FolderFullPath = "/lists/" + listName + "/" + relativePath;
        }
        if (!string.IsNullOrEmpty(FolderFullPath))
        {
            query.FolderServerRelativeUrl = FolderFullPath;
        }
        IList<Folder> folderResult = new List<Folder>();

        var listItems = list.GetItems(query);

        clientContext.Load(list);
        clientContext.Load(listItems, litems => litems.Include(
            li => li["DisplayName"],
            li => li["Id"]
            ));

        clientContext.ExecuteQuery();

        foreach (var item in listItems)
        {

            Console.WriteLine("{0}----------{1}", item.Id, item.DisplayName);
        }
    }
}
As shown above, the CamlQuery.CreateAllFoldersQuery method generate a query which will query folders. You can pass that query in any list’s GetItems method to get the folders of that list. You can also specify the root folder from which to start searching for folder by specifying the CamlQuery.FolderServerRelativeUrl property.

Conclusion

Client OM has opened a new window on SharePoint programming. I have found it very useful as it exposed almost full power of SharePoint on client side.