我是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;
尽管第一部分可以工作,但是在更改代码之前已经做到了。
更新2
更新3 根据评论更新了代码,但是仍然没有。
更新4:解决方案
事实证明,实际的问题是安装了名为 Microsoft.SharePoint.Client v.14.xxxx的nuget软件包。应该是刚刚被称为 SharePoint.Client v.15.xxxx的版本(该版本没有描述,但来自Microsoft)。
因此,感谢亚当(Adam)的帮助,我将您的回答标记为正确,因为它最终导致我遇到了问题,因此可以解决。 安装正确的软件包可立即解决此问题。
更新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.
}
}
答案 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} "); } }
请注意
如果您打算使用该库中的文件夹并将某些文件放入文件夹中,则此方法还不够:)。您将需要首先将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 = ....
参数中看到该名称。