从SharePoint Online / 365检索文件

时间:2019-10-04 10:32:11

标签: sharepoint-online csom

我是SharePoint的新手,我的确意识到有很多与此主题相关的帖子,我也已经阅读了这些帖子,但是我仍然不确定该怎么做。

我尝试使用CSOM .NET实现这一目标(实际上,我更喜欢使用REST API,但是事实证明,整个Azure注册工作都是对它自己的研究,因此我改用托管代码)。

无论如何,有一个SP网站,我知道它通往“ https://(server)/sites/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获得帮助,但是这些工具都不显示我正在寻找的图片网站(或列表或文件夹)。 / p>

我认为对于习惯于通过CSOM来查询SP资源的方法不是那么直观的人来说,这应该是很简单的。

因此,任何人都可以从这里指导我的工作,因此以某种方式列出文件,以便可以下载它们(文件的链接应该在这方面起作用)。

感谢您的帮助。

更新1

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

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

enter image description here

尽管第一部分可以工作,但是在更改代码之前已经做到了。

enter image description here

更新2

enter image description here

更新3 根据评论更新了代码,但是仍然没有。

enter image description here

enter image description here

更新4:解决方案

事实证明,实际的问题是安装了名为 Microsoft.SharePoint.Client v.14.xxxx的nuget软件包。应该是刚刚被称为 SharePoint.Client v.15.xxxx的版本(该版本没有描述,但来自Microsoft)。

因此,感谢亚当(Adam)的帮助,我将您的回答标记为正确,因为它最终导致我遇到了问题,因此可以解决。 安装正确的软件包可立即解决此问题。 enter image description here

正确的包装就是这个。 enter image description here

更新5:新主题,自定义字段/列(仍使用CSOM)

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

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

1 个答案:

答案 0 :(得分:2)

也请将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} ");
        }
    }

上面的示例库代码输出如下: enter image description here

请注意

如果您打算使用该库中的文件夹并将某些文件放入文件夹中,则此方法还不够:)。您将需要首先将lst_pictures.RootFolder.Folders加载到上下文,然后执行该操作,然后遍历每个文件夹的集合,并针对每个文件夹,您将需要加载此文件夹的文件集合以获取文件。 总结一下,您将需要:


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

但是,如果您仅打算将文件保留在库的根文件夹中,则第一个代码应该是您要查找的内容。 希望这篇文章对您有所帮助:)

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可以将空格更改为 x0020 。因此,对于列显示名称(如“自定义列1”),内部名称为“ Custom_x0020_Column_x0020_1”,这是您应使用的名称。您可以通过转到列设置页面(编辑页面)获得此名称,然后您将在URL中的Field = ....

参数中看到该名称。