从 SharePoint 检索文件 Online/365

Retrieve files from SharePoint Online/365

我是 SharePoint 的新手,我知道有几篇关于这个主题的帖子,我也通读了它们,但我仍然不确定如何去做。

我尝试使用 CSOM .NET 来实现这一点(实际上我更喜欢使用 REST API,但是整个 Azure 注册的事情被证明是对它自己的研究,所以我使用了托管代码相反)。

无论如何,有一个 SP 站点我知道“https://(server)/sites/Pictures/”的路径。这个地方(站点、列表、文件夹或任何名称)包含一些我希望能够列出并可能下载的图像。

执行以下操作得到名称:"Pictures"、计数:393 和 ServerRelativeUrl:“/sites/Pictures/Pictures”。

    using (ClientContext ctx = new ClientContext(site_url))
    {
        ctx.Credentials = new SharePointOnlineCredentials(usr, secure_pwd);

        Web web = ctx.Web;

        List lst_pictures = web.Lists.GetByTitle("Pictures");

        ctx.Load(lst_pictures.RootFolder);

        ctx.ExecuteQuery();

        Console.WriteLine("Name: " + lst_pictures.RootFolder.Name);
        Console.WriteLine("ItemCount: " + lst_pictures.RootFolder.ItemCount);
        Console.WriteLine("ServerRelativeUrl: " + lst_pictures.RootFolder.ServerRelativeUrl);
    }

从这里开始,我尝试了几种方法来列出和循环文件,但无论我尝试什么,我总是收到同样的异常,说集合还没有被初始化,我似乎无法得到它对。

然后我尝试查看是否可以使用 U2U CAM 查询生成器和 CAML Designer for SharePoint 获得帮助,但是这些工具都没有显示我正在寻找的图片网站(或列表或文件夹) .

我认为对于那些习惯于通过 CSOM 以不太直观的方式查询 SP 资源的人来说,这应该是非常简单的。

所以,任何人都可以指导我从这里做什么,所以以某种方式列出文件以便可以下载它们(文件的 link 应该在这方面做到)。

感谢任何帮助,谢谢。

更新 1

我添加了您建议的行,我很确定我在之前的测试中已经在我的代码中添加了这些行,但我再次删除了它们,因为它对我不起作用 - 而且它仍然没有't :( 请在此处查看图片。

// lines not shown in the image
ctx.Load(lst_pictures.RootFolder);
ctx.Load(lst_pictures.RootFolder.Files);

ctx.ExecuteQuery();

Console.WriteLine("Name: " + lst_pictures.RootFolder.Name);
Console.WriteLine("ItemCount: " + lst_pictures.RootFolder.ItemCount);
Console.WriteLine("ServerRelativeUrl: " + lst_pictures.RootFolder.ServerRelativeUrl):

FileCollection files = lst_pictures.RootFolder.Files;

虽然第一部分有效,但它是在更改代码之前完成的。

更新 2

更新 3 根据评论更新了代码,还是不行

更新 4:解决方案

事实证明,实际问题是安装的名为 Microsoft.SharePoint.Client v.14.xxxx 的 nuget 包。应该就是刚刚那个叫SharePoint.Client v.15.xxxx的(这个没有说明,来自微软)

所以,感谢 Adam 试图帮助我,我会将你的答案标记为正确的,因为它最终引导我找到了问题,所以它可以被修复。 安装正确的包立即解决了这个问题。

正确的包是这个。

更新 5:新主题,自定义 fields/columns(仍在使用 CSOM)

1) 目前我有以下代码,但我需要从文件中获取一些额外的属性(自定义属性)——我应该在代码中添加什么才能做到这一点? 2)在这种情况下我应该使用 ListItem 而不是 File 吗? 3) 我什至可以在自定义 fields/columns 上添加过滤以便只检索文件的子集吗?

        using (ClientContext ctx = new ClientContext("<url>"))
        {
            ctx.Credentials = new SharePointOnlineCredentials("<usr>", "<pwd>");

            Web web = ctx.Web;

            lst = web.Lists.GetByTitle("<list name>");

            ctx.Load(lst);
            ctx.Load(lst.RootFolder);
            ctx.Load(lst.RootFolder.Folders);

            ctx.ExecuteQuery();

            files = lst.RootFolder.Files;

            foreach (File f in files)
            {
                // doing stuff with some attributes like UniqueId, Name and ServerRelativeUrl, but need custom attributes as well.
            }
        }

请将 rootFolder 的文件也加载到上下文中,例如:


    ctx.Load(lst_pictures.RootFolder.Files);

然后您可以在库的根文件夹中获取文件集合,例如:


    FileCollection fileCollection = lst_pictures.RootFolder.Files;

基于您的代码的完整代码如下:


    using (ClientContext ctx = new ClientContext(site_url))
    {
        ctx.Credentials = new SharePointOnlineCredentials(usr, secure_pwd);

        Web web = ctx.Web;

        List lst_pictures = web.Lists.GetByTitle("Pictures");

        ctx.Load(lst_pictures.RootFolder);

        // Load files of root folder to context
        ctx.Load(lst_pictures.RootFolder.Files);

        // after execute on context the rootFolder will be populated with file collection
        ctx.ExecuteQuery();

        Console.WriteLine("Name: " + lst_pictures.RootFolder.Name);
        Console.WriteLine("ItemCount: " + lst_pictures.RootFolder.ItemCount);
        Console.WriteLine("ServerRelativeUrl: " + lst_pictures.RootFolder.ServerRelativeUrl);

        // get the file collection of the rootfolder
        FileCollection fileCollection = lst_pictures.RootFolder.Files;
        foreach (File file in fileCollection)
        {
            Console.WriteLine($"file : {file.Name} ");
        }
    }

我的示例库的上述代码输出如下:

请注意

如果您计划使用此库中的文件夹并将一些文件放入文件夹中,这种方法是不够的:)。您需要先将 lst_pictures.RootFolder.Folders 加载到上下文,然后执行,然后执行 foreach 文件夹集合,对于每个文件夹,您需要加载该文件夹的文件集合以获取文件。 总而言之,您需要:


    ctx.Load(lst_pictures.RootFolder);
    ctx.Load(lst_pictures.RootFolder.Folders);
    ctx.ExecuteQuery();

然后


    FolderCollection folderCollection = lst_pictures.RootFolder.Folders;
    foreach (Folder folder in folderCollection)
    {
           ctx.Load(folder.Files);
           ctx.ExecuteQuery();
           FileCollection fileCollection = folder.Files;
           foreach (File file in fileCollection)
           {
                 Console.WriteLine($"file : {file.Name} ");
           }
    }

但是如果您打算只将文件保存在库的根文件夹中,那么第一个代码应该就是您要查找的内容。 我希望这篇 post 对您有所帮助 :)

P.S。 欢迎使用 SharePoint。

更新 1

如果您想在文件集合中包含自定义列,您需要包含它们。您可以像这样包含所有自定义文件列



    ctx.Load(list.RootFolder);
    ctx.Load(list.RootFolder.Folders);
    ctx.Load(list.RootFolder.Files, includes => includes.Include(i => i.Name, i => i.ListItemAllFields));
    ctx.ExecuteQuery();

然后您拥有所有列的列表以及自定义列。所以你可以像这样做一个foreach:



    FileCollection fileCollection = list.RootFolder.Files;
    foreach (File file in fileCollection)
    {
          Console.WriteLine($"file : {file.Name} ");
          Console.WriteLine($"file : {file.ListItemAllFields["SomeCustomColumn"]} ");
     }

仅获取所需的自定义列您可以像这样一一包含它们



    ctx.Load(list.RootFolder.Files, includes => includes.Include(i => i.Name, i => i.ListItemAllFields["CustomColumn1"], i => i.ListItemAllFields["CustomColumn2"]));

然后对于此文件集合,集合中应该只有名称和两个自定义列。

另请注意,此列的名称是内部字段名称(或静态名称)而不是显示名称,因此 SharePoint 例如可以将 space 更改为 x0020。因此,对于像 "Custom Column 1" 这样的列显示名称,内部名称是 "Custom_x0020_Column_x0020_1",这是您应该使用的名称。您可以通过转到列设置页面(编辑页面)来获取此名称,您将在参数 Field=....

中的 url 中看到该名称