[CSOM] Test in your C# code if a SharePoint File or Folder exists
A Simple Use Case
When you want to know if a file or folder already exists on a SharePoint Site (in a migration use case for example, before perform a copy / move), you can have some bad surprises.
Let's try with a simple folder case example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 | string userName = "user@tenant.onmicrosoft.com";
SecureString securePassword = new SecureString();
foreach (var cc in "yourPlainTextPassword")
{
securePassword.AppendChar(cc);
}
using (ClientContext spContext = new ClientContext("SharePointSiteUrl"))
{
spContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);
spContext.ExecuteQuery();
Web currentWeb = spContext.Web;
List docLibrary = currentWeb.Lists.GetByTitle("Documents");
spContext.Load(docLibrary);
spContext.Load(docLibrary.RootFolder);
spContext.ExecuteQuery();
string folderPath = docLibrary.RootFolder.ServerRelativeUrl + "/MyFolderThatDoesNotExists";
Folder folderToGet = currentWeb.GetFolderByServerRelativeUrl(folderPath);
spContext.Load(folderToGet, f => f.Exists);
try
{
spContext.ExecuteQuery();
if (folderToGet.Exists)
{
// Do something
}
else
{
// Do something else
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
|
The twisted thing here's that the if (folderToGet.Exists)
line won't be reached. Because if you use the "GetFolderByServerRelativeUrl" and the folder actually doesn't exists (or any parent folder in the hierarchy), it'll throw an exception. But if it exists, then you'll be able to test the value of folderToGet.Exists
property (which obviously will return true
). Clever.
So you want to test if a folder exists but without to constantly catch the error... Good news : the SharePointPnPCoreOnline Package implements this ! Let's try it :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | // Credentials declaration like above
...
using (ClientContext spContext = new ClientContext("SharePointSiteUrl"))
{
// Connection like above
...
string folderPath = docLibrary.RootFolder.ServerRelativeUrl + "/MyFileThatDoesNotExists";
bool exists = currentWeb.DoesFolderExists(folderPath);
if (exists)
{
// Do something
}
else
{
// Do something else
}
}
|
And that's it ! The DoesFolderExists
Method provides this test. And it also works with folder hierarchy containing special characters 😉.
For testing the existance of a file, there's not any equivalent. So if you try to get a file that doesn't exists :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | // Credentials declaration like above
...
using (ClientContext spContext = new ClientContext("SharePointSiteUrl"))
{
// Connection like above
...
string filePath = docLibrary.RootFolder.ServerRelativeUrl + "/MyFileThatDoesNotExists";
File fileToGet = currentWeb.GetFileByServerRelativeUrl(filePath);
spContext.Load(fileToGet, f => f.Exists);
try
{
spContext.ExecuteQuery();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
|
It'll also throw an exception.
So the thing here is to use the GetFileByServerRelativePath
method which returns a File object, whether it exists or not. And there : the "Exists" property can be used. The great thing about this method is that it also works if you file (or your folder hierarchy) contains special characters:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | // Credentials declaration like above
...
using (ClientContext spContext = new ClientContext("SharePointSiteUrl"))
{
// Connection like above
...
string filePath = docLibrary.RootFolder.ServerRelativeUrl + "/# My Tricky File ühühü.docx";
File fileToGet = currentWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(filePath));
spContext.Load(fileToGet, f => f.Exists);
try
{
spContext.ExecuteQuery();
if (fileToGet.Exists)
{
// Do something
}
else
{
// Do something else
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
|
Bonus : Using the Windows Credential Manager
For Windows users, if you don't want to always write your credentials and if you already know the Add/Get-PnPStoredCredential cmdlets, you might be interested to use the CredentialManager class provided by the Adys Tech company. You can fin the Nugget package here.
Then, when referencing it, you just have to use it like this:
| var cred = CredentialManager.GetCredentials("PnPPS:CredentialsName");
string user = cred.UserName;
SecureString pwd = cred.SecurePassword;
|
Useful Links