C# CSOM - 检查文档库中文件是否存在

11
我正在使用CSOM编写C#代码,我的应用程序将一个模板ASP.NET页面上传到“/Pages/”库中,我需要检查该位置是否存在同名文件,然后再进行文件上传(也许可以返回一个bool值)。 我已经快速查看了一下,但是我找到的大多数解决方案都涉及使用Javascript,或者适用于本地部署。 如果有人能指点我正确的方向,我将不胜感激。
5个回答

17

您可以考虑以下方法来确定文件是否存在。

基于查询

您可以构建CAML查询,通过其Url查找列表项,如下所示:

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;
}

使用方法

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

Web.GetFileByServerRelativeUrl方法

使用Web.GetFileByServerRelativeUrl方法返回位于指定服务器相关 URL 的文件对象。

如果文件不存在,将会遇到异常Microsoft.SharePoint.Client.ServerException

  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;
        }
    }

用法:

 using (var ctx = GetSPOContext(webUri,userName,password))
 {
      Microsoft.SharePoint.Client.File file;
      if(TryGetFileByServerRelativeUrl(ctx.Web,"/documents/SharePoint User Guide.docx",out file))
      {
          //...
      }
 }    

1
基于查询的解决方案运行完美。两者之间有什么区别?为什么会选择其中之一?再次感谢! - Junior
1
我也更喜欢基于查询的方法而不是第二种方法。但在某些情况下,从性能角度考虑使用第二种方法可能会有好处。 - Vadim Gremyachev
1
对于Web.GetFileByServerRelativeUrl方法,请注意,如果您的站点位于URL顶部以下的文件夹级别,则可能需要指定更多内容,而不仅仅是“/documents/doc.docx”。我不得不指定主机名后面的所有内容...例如,“/sites/dept/hr/subsitename/documents/doc.docx”。 - vwfreak

11

Web.GetFileByServerRelativeUrl(@vadim上面发布的)的替代方法是 Load(checkFile, p => p.Exists);,在上下文中...

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
    }
}

1
同意。通常会导致检查失败的是ctx.Load(file),因为如果文件不存在,则无法加载文件对象。您通过仅加载Exists属性来正确处理它。 - Martin D
我尝试了这种方法,对于有效和无效的文件名,我都得到了Exists属性而没有任何异常。 - Abdul Hameed
完美地运作。我认为这是最佳答案,因为它不像其他人在这里建议的那样使用任何盲目的异常陷阱。 - Boris Zinchenko

8

如果您正在使用客户端对象模型(Client OM),如果文件不存在,它将实际上抛出异常:

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 )
     {
           .
           .
     }
}

资源


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;

        }

    }

0

还有一个客户端可调用的Web.GetFileByUrl(string absOrServerRelUrl)函数,与Web.GetFileByServerRelativeUrl|Path相同,但如果文件不存在,则返回Exist=false的File对象(而其他函数会显式抛出异常)。 它们都在内部调用SPWeb.GetFile(该函数不可由客户端调用),可以通过ILSpy进行检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接