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:
- private bool FileExists(ClientContext clientContext, String docLibTitle, String fileName, String rootFolderServerRelativeUrl, String folderPath)
- {
- var folderServerRelativeUrl = string.Format("{0}/{1}", rootFolderServerRelativeUrl, folderPath);
- // or use a helper method to combine URL parts
- //var folderServerRelativeUrl = JoinUrlParts(rootFolderServerRelativeUrl, folderPath);
- List DocumentsList = clientContext.Web.Lists.GetByTitle(docLibTitle);
- CamlQuery camlQuery = new CamlQuery();
- camlQuery.ViewXml = @"<View Scope='Recursive'>
- <Query>
- <Where>
- <Eq>
- <FieldRef Name='FileLeafRef'></FieldRef>
- <Value Type='Text'>" + fileName + @"</Value>
- </Eq>
- </Where>
- </Query>
- </View>";
- camlQuery.FolderServerRelativeUrl = folderServerRelativeUrl;
- ListItemCollection listItems = DocumentsList.GetItems(camlQuery);
- clientContext.Load(listItems);
- clientContext.ExecuteQuery();
- return listItems.Count > 0;
- }
Usage:
- var webUrl = "http://YourSharePoint/site/subsite";
- string docLibTitle = "Documents";
- var rootFolderServerRelativeUrl = "/site/subsite/Shared Documents";
- var folderPath = "folder/subfolder";
- ClientContext clientContext = new ClientContext(webUrl);
- var fileName = "document.docx";
- 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:
- public static string JoinUrlParts(params string[] urlParts)
- {
- return string.Join("/", urlParts.Where(up => !string.IsNullOrEmpty(up)).ToList().Select(up => up.Trim('/')).ToArray());
- }
If you, however, know only the title of the document library but not its server relative URL you need two round-trips:
- private bool FileExists(ClientContext clientContext, String docLibTitle, String fileName, String folderPath)
- {
- List docLib = clientContext.Web.Lists.GetByTitle(docLibTitle);
- Folder rootFolder = docLib.RootFolder;
- clientContext.Load(rootFolder, f => f.ServerRelativeUrl);
- clientContext.ExecuteQuery();
- string rootFolderServerRelativeUrl = rootFolder.ServerRelativeUrl;
- var folderServerRelativeUrl = string.Format("{0}/{1}", rootFolderServerRelativeUrl, folderPath);
- // or use a helper method to combine URL parts
- //var folderServerRelativeUrl = JoinUrlParts(rootFolderServerRelativeUrl, folderPath);
- Folder folder = clientContext.Web.GetFolderByServerRelativeUrl(folderServerRelativeUrl);
- clientContext.Load(folder);
- CamlQuery camlQuery = new CamlQuery();
- camlQuery.ViewXml = @"<View Scope='Recursive'>
- <Query>
- <Where>
- <Eq>
- <FieldRef Name='FileLeafRef'></FieldRef>
- <Value Type='Text'>" + fileName + @"</Value>
- </Eq>
- </Where>
- </Query>
- </View>";
- camlQuery.FolderServerRelativeUrl = folderServerRelativeUrl;
- ListItemCollection listItems = docLib.GetItems(camlQuery);
- clientContext.Load(listItems);
- clientContext.ExecuteQuery();
- return listItems.Count > 0;
- }
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:
- var webUrl = "http://YourSharePoint/site/subsite";
- var docLibTitle = "Documents";
- var folderPath = "folder/subfolder";
- ClientContext clientContext = new ClientContext(webUrl);
- var fileName = "document.docx";
- bool fileFound = FileExists(clientContext, docLibTitle, fileName, folderPath);