从 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 中看到该名称
我是 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 中看到该名称