Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

This is my first post, so I'd like to say hello to everyone.

I'm trying to get Folder object by its path in SharePoint 2010 client application using Client Side Object Model (.Net 4.0).

I need to check whether folder described by 'folderPath' variable exists in the library and then get the Folder object for further operations. To enhance performance, I chose to use CAML query to filter the list.

My code:

IEnumerable<List> library = this.clientContext.LoadQuery(
    this.clientContext.Web.Lists.Where(p => p.Title == this.documentLibrary));
this.clientContext.ExecuteQuery();
List libraryList = library.FirstOrDefault();
//code to handle libraryList == null

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

ListItemCollection items = libraryList.GetItems(camlQuery);
clientContext.Load(items);
clientContext.ExecuteQuery();

To this point everything is OK. But I don't have any idea how get the 'Folder' object from an item. I tried to do it in this way:

Folder folder = items.FirtsOrDefault().Folder;
clientContext.Load(folder);
clientContext.ExecuteQuery();

and that way (used instead of last three lines from first code snippet):

ListItemCollection items = libraryList.GetItems(camlQuery);
clientContext.Load(items, collection => collection.Include(item => item.Folder));
clientContext.ExecuteQuery();

But in both cases I got an Exception:

1st: 'Field or property 'Folder' does not exist.'

2nd: 'Column 'Folder' does not exist. It may have been deleted by another user.'

Is there a way to do it? Or maybe I'm doing something wrong? Thanks in advance for the help.

share|improve this question
    
possible duplicate of CSOM Get ListItem of Folder –  RJ Cuthbertson Mar 14 at 14:03
    
Don't know what is better: possible duplicate or answering your own question after half an hour: link, and an hour: link :) –  adams Mar 14 at 14:18
    
I retracted that close vote because your question is different; it's almost the reverse of the one in the auto-generated comment. But there's nothing wrong with answering your own questions. It just means I figured it out myself before someone else answered. Even still, asking a question and answering it in one fell swoop is still supported, and is given as an option via the UI when asking a question (that's what the checkbox marked "Answer your own question" is for). See: meta.sharepoint.stackexchange.com/questions/386/… –  RJ Cuthbertson Mar 14 at 14:35

3 Answers 3

up vote 6 down vote accepted

It actually depends on which version of SharePoint is used.

SharePoint 2013

In SharePoint 2013 CSOM ListItem.Folder property gets a folder object that is associated with a folder item.

SharePoint 2010

In SharePoint 2010 CSOM Folder property is not exposed for ListItem object.

The following method could be used for retrieving Folder associated with ListItem:

/// <summary>
/// Get Parent Folder for List Item
/// </summary>
/// <param name="listItem"></param>
/// <returns></returns>
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;
}

Example:

using (var context = new ClientContext(webUrl))
{
      var list = context.Web.Lists.GetByTitle(listTitle);
      var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
      context.Load(items);
      context.ExecuteQuery();


      foreach (var item in items)
      {
         var folder = GetListItemFolder(item); //get Folder
         Console.WriteLine(folder.Name);
      }
}
share|improve this answer
    
So there is no other way than using GetFolderByServerRelativeUrl method? –  adams Mar 14 at 12:36
    
I believe this is the only way, if you need to get Folder object associated with ListItem object in SPS 2010 –  Vadim Gremyachev Mar 14 at 12:47
    
I did not notice that I am using wrong Microsoft.SharePoint.Client and Microsoft.SharePoint.Client.Runtime dlls to communicate with SP 2010. I created my project with VS 2013 and referenced dlls were in 15.0.0.0 version. That's why I got Folder property in ListItem object (which is available in SP 2013). After change dlls reference to 14.0.0.0 version Folder property is not available any more. Your post helped me to understand this problem, so I will check it as an answer (despite the fact that Camerons post with GetFolderByServerRelativeUrl method was the first one). –  adams Mar 14 at 13:45
1  
It doesn't matter which answer is first. You should accept the best answer, and upvote any answers that were helpful. –  RJ Cuthbertson Mar 14 at 14:05

You could use this:

clientContext.Load(libraryList.RootFolder, spFolder => spFolder.ServerRelativeUrl);
clientContext.ExecuteQuery();

var folderServerRelativePath = string.Format("0}/{1}",
  libraryList.RootFolder.ServerRelativeUrl.TrimEnd('/'), 
  folderPath.TrimStart('/')
);
clientContext.Web.GetFolderByServerRelativeUrl(folderServerRelativePath)

You can use the same approach you started with to filter, but then you'd need the libraryList.RootFolder.Folders property.

share|improve this answer
    
Sorry, I don't have enough reputation to mark your answer as useful at the moment. –  adams Mar 14 at 13:55
    
Kinda the same as what the other guy answered after me. –  Cameron Verhelst Mar 14 at 13:56

Try the following way:

To get the folder you have to user SPFolder instead of Folder.

    SPFile fItem= item.Web.GetFile(item.Url);  
    SPFolder folder = fItem.ParentFolder; 

Try this if it works.

Edit

To get folder of each item you should place the code in foreach() loop

share|improve this answer
3  
I am not able to use SPFile/SPFolder since I'm using client side object model. 'SP*' classes are only available on the server side. –  adams Mar 14 at 11:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.