C# CSOM - Check if File Exists in Document Library
Asked Answered
H

5

11

I'm coding in C# using CSOM, my app uploads a template asp.net page to the "/Pages/" library, I need it to check if a file exists in that location with the same name prior to file upload (then maybe it can return a bool value).

I did have a quick look but the majority of the solutions I found referred to the use of Javascript, or applied to on-prem deployments.

If someone could please point me in the right direction I would appreciate it.

Horsa answered 11/3, 2015 at 1:37 Comment(0)
S
17

You could consider the following approaches to determine whether file exists or not.

Query based

You could construct CAML query to find list item by its Url as demonstrated below:

public static bool FileExists(List list, string fileUrl)
{
    var ctx = list.Context;
    var qry = new CamlQuery();
    qry.ViewXml = string.Format("<View Scope=\"RecursiveAll\"><Query><Where><Eq><FieldRef Name=\"FileRef\"/><Value Type=\"Url\">{0}</Value></Eq></Where></Query></View>",fileUrl);
    var items = list.GetItems(qry);
    ctx.Load(items);
    ctx.ExecuteQuery();
    return items.Count > 0;
}

Usage

using (var ctx = GetSPOContext(webUri,userName,password))
{
     var list = ctx.Web.Lists.GetByTitle(listTitle);
     if(FileExists(list,"/documents/SharePoint User Guide.docx"))
     {
          //...
     }
}

Web.GetFileByServerRelativeUrl Method

Use Web.GetFileByServerRelativeUrl Method to return the file object located at the specified server-relative URL.

If file does not exists the exception Microsoft.SharePoint.Client.ServerException will be encountered:

  public static bool TryGetFileByServerRelativeUrl(Web web, string serverRelativeUrl,out Microsoft.SharePoint.Client.File file)
    {
        var ctx = web.Context;
        try{
            file = web.GetFileByServerRelativeUrl(serverRelativeUrl);
            ctx.Load(file);
            ctx.ExecuteQuery();
            return true;
        }
        catch(Microsoft.SharePoint.Client.ServerException ex){
            if (ex.ServerErrorTypeName == "System.IO.FileNotFoundException")
            {
                file = null;
                return false;
            }
            else
                throw;
        }
    }

Usage:

 using (var ctx = GetSPOContext(webUri,userName,password))
 {
      Microsoft.SharePoint.Client.File file;
      if(TryGetFileByServerRelativeUrl(ctx.Web,"/documents/SharePoint User Guide.docx",out file))
      {
          //...
      }
 }    
Stakhanovism answered 11/3, 2015 at 9:13 Comment(3)
The query based solution works perfectly. Between the two - what's the difference? Why would you use one over the other? Thanks again!Horsa
I would also prefer query based approach over the second one. But in some cases you could gain benefits using the second approach from performance perspectiveStakhanovism
For the Web.GetFileByServerRelativeUrl Method, note that you will probably need to specify more than just "/documents/doc.docx" if your site is sitting at a folder level below the top of the url. I had to specify everything after the hostname... for example "/sites/dept/hr/subsitename/documents/doc.docx"Rhetorician
T
12

An alternative to the Web.GetFileByServerRelativeUrl (@vadim posted above) is Load(checkFile, p => p.Exists); and in context ...

using (ClientContext ctx = new ClientContext("https://yoursubdomainhere.sharepoint.com/"))
{
    Web web = ctx.Web;
    Microsoft.SharePoint.Client.File checkFile = web.GetFileByServerRelativeUrl("/sites/Documents/MyFile.docx");

    ctx.Load(checkFile, fe => fe.Exists);
    ctx.ExecuteQuery();
    if (!checkFile.Exists)
    {
        //Do something here
    }
}
Towhee answered 27/5, 2016 at 5:35 Comment(3)
Agreed. What usually breaks the check is actually ctx.Load(file) because the file object can't be loaded if it doesn't exist. You have it right by loading only the Exists property.Toxin
tried this approach and i got Exists property without any exception for valid and invalid file names.Morass
Works perfectly well. I think it is best answer because it does not use any blind exception traps as others suggest here.Spender
T
8

if you are using Client OM, it would actually throw an exception if the file doesn't exist:

using(var clientContext = new ClientContext(site))
{
     Web web = clientContext.Web;
     Microsoft.SharePoint.Client.File file = web.GetFileByServerRelativeUrl("/site/doclib/folder/filename.ext");
     bool bExists = false;
     try
     {
         clientContext.Load(file);
         clientContext.ExecuteQuery(); //Raises exception if the file doesn't exist
         bExists = file.Exists;  //may not be needed - here for good measure
     }
     catch{   }

     if (bExists )
     {
           .
           .
     }
}

Resource

Tieck answered 11/3, 2015 at 6:48 Comment(0)
Y
4

Using Linq To SharePoint

    public bool FolderExists(string library, string name) {

        using (var ctx = SPStatic.Context(_sharePointSiteUrl)) {

            List sharedDocs = ctx.Web.Lists.GetByTitle(library);

            var query = ctx.LoadQuery(sharedDocs.RootFolder.Folders.Where(fd => fd.Name == name));

            ctx.ExecuteQuery();

            Folder f = query.SingleOrDefault();

            return f != null;

        }

    }
Yogurt answered 2/10, 2015 at 16:52 Comment(0)
C
0

There is also a client-callable Web.GetFileByUrl(string absOrServerRelUrl) functioning identically to Web.GetFileByServerRelativeUrl|Path, but returning a File object with Exist=false (while the others throw explicitly) if the file does not exist. They all call SPWeb.GetFile internally (which is not client-callable), check via ILSpy.

Censer answered 16/1, 2023 at 20:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.