Second Life of a Hungarian SharePoint Geek

March 23, 2018

How to check if a specific file exists in a folder structure of a SharePoint document library using the client object model

Filed under: CAML, Managed Client OM, SP 2013 — Tags: , , — Peter Holpar @ 22:25

Recently we had to create a utility function that makes it us possible to check if a file having a specific name exists anywhere within a folder structure of a SharePoint document library.

As long as you know not only the title of the document library, but its server relative URL as well, it requires only a single round-trip to the server:

  1. private bool FileExists(ClientContext clientContext, String docLibTitle, String fileName, String rootFolderServerRelativeUrl, String folderPath)
  2. {
  3.     var folderServerRelativeUrl = string.Format("{0}/{1}", rootFolderServerRelativeUrl, folderPath);
  4.     // or use a helper method to combine URL parts
  5.     //var folderServerRelativeUrl = JoinUrlParts(rootFolderServerRelativeUrl, folderPath);
  6.  
  7.     List DocumentsList = clientContext.Web.Lists.GetByTitle(docLibTitle);
  8.  
  9.     CamlQuery camlQuery = new CamlQuery();
  10.     camlQuery.ViewXml = @"<View Scope='Recursive'>
  11.                         <Query>
  12.                             <Where>
  13.                                 <Eq>
  14.                                     <FieldRef Name='FileLeafRef'></FieldRef>
  15.                                     <Value Type='Text'>" + fileName + @"</Value>
  16.                                 </Eq>
  17.                             </Where>
  18.                         </Query>
  19.                 </View>";
  20.     camlQuery.FolderServerRelativeUrl = folderServerRelativeUrl;
  21.     ListItemCollection listItems = DocumentsList.GetItems(camlQuery);
  22.     clientContext.Load(listItems);
  23.     clientContext.ExecuteQuery();
  24.  
  25.     return listItems.Count > 0;
  26. }

Usage:

  1. var webUrl = "http://YourSharePoint/site/subsite&quot;;
  2. string docLibTitle = "Documents";
  3. var rootFolderServerRelativeUrl = "/site/subsite/Shared Documents";
  4. var folderPath = "folder/subfolder";
  5.  
  6. ClientContext clientContext = new ClientContext(webUrl);
  7. var fileName = "document.docx";
  8.  
  9. bool fileFound = FileExists(clientContext, docLibTitle, fileName, rootFolderServerRelativeUrl, folderPath);

Note: If the folderServerRelativeUrl points to a location not within the document library (rootFolderServerRelativeUrl is wrong), the CAML query will ignore the FolderServerRelativeUrl and the entire library will be searched for a matching file. If  the folderPath part is wrong (not existing folder) then no matching item will be found, the query will return always false. Although the SPFolder server-side object model provides an Exists property to check if the folder at the given oath exists, there is no such property for the Folder object in the client object model. As a workaround, you can detect such mistakes by including these two lines of code in the FileExists method before invoking the ExecuteQuery method:

Folder folder = clientContext.Web.GetFolderByServerRelativeUrl(folderServerRelativeUrl);
clientContext.Load(folder);

If either part of the folderServerRelativeUrl is wrong, a File not found exception will be thrown on calling the ExecuteQuery method.

The helper method mentioned in the code is useful if you would not like to bother with leading and trailing slashes in the URL and in the folder path:

  1. public static string JoinUrlParts(params string[] urlParts)
  2. {
  3.     return string.Join("/", urlParts.Where(up => !string.IsNullOrEmpty(up)).ToList().Select(up => up.Trim('/')).ToArray());            
  4. }

If you, however, know only the title of the document library but not its server relative URL you need two round-trips:

  1. private bool FileExists(ClientContext clientContext, String docLibTitle, String fileName, String folderPath)
  2. {
  3.     List docLib = clientContext.Web.Lists.GetByTitle(docLibTitle);
  4.     Folder rootFolder = docLib.RootFolder;
  5.     clientContext.Load(rootFolder, f => f.ServerRelativeUrl);
  6.     clientContext.ExecuteQuery();
  7.  
  8.     string rootFolderServerRelativeUrl = rootFolder.ServerRelativeUrl;
  9.     var folderServerRelativeUrl = string.Format("{0}/{1}", rootFolderServerRelativeUrl, folderPath);
  10.     // or use a helper method to combine URL parts
  11.     //var folderServerRelativeUrl = JoinUrlParts(rootFolderServerRelativeUrl, folderPath);
  12.  
  13.     Folder folder = clientContext.Web.GetFolderByServerRelativeUrl(folderServerRelativeUrl);
  14.     clientContext.Load(folder);
  15.  
  16.     CamlQuery camlQuery = new CamlQuery();
  17.     camlQuery.ViewXml = @"<View Scope='Recursive'>
  18.                         <Query>
  19.                             <Where>
  20.                                 <Eq>
  21.                                     <FieldRef Name='FileLeafRef'></FieldRef>
  22.                                     <Value Type='Text'>" + fileName + @"</Value>
  23.                                 </Eq>
  24.                             </Where>
  25.                         </Query>
  26.                 </View>";
  27.     camlQuery.FolderServerRelativeUrl = folderServerRelativeUrl;
  28.     ListItemCollection listItems = docLib.GetItems(camlQuery);
  29.     clientContext.Load(listItems);
  30.     clientContext.ExecuteQuery();
  31.  
  32.     return listItems.Count > 0;
  33. }

Note: This version already includes the two-liner to check the existence of the folder path. If you don’t need that, remove it.

Usage of this version:

  1. var webUrl = "http://YourSharePoint/site/subsite&quot;;
  2. var docLibTitle = "Documents";
  3. var folderPath = "folder/subfolder";
  4. ClientContext clientContext = new ClientContext(webUrl);
  5. var fileName = "document.docx";
  6.  
  7. bool fileFound = FileExists(clientContext, docLibTitle, fileName, folderPath);

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: