自动将所有附件下载到 SharePoint 项目
Downloading all Attachments to a SharePoint Item automatically
我有一个最终会 运行 作为控制台应用程序的控制台应用程序。我需要循环访问外部 Sharepoint 站点,查找所有新项目并查看是否有任何附件,如果有,我需要下载这些附件。
我能够查询列表,并且能够遍历附件以填充文件集合。
FolderToSaveTo 解析为“\\APPDEV03\NEMStoPSIMS\”并传递 if (System.IO.Directory.Exists(destPath)) 语句,但在下一行使用 (Stream destFile = System.IO.File.OpenWrite(destPath) ) 抛出 {"The filename, directory name, or volume label syntax is incorrect.\r\n"}
我可以导航到 \APPDEV03\NEMStoPSIMS\ 并且可以手动保存文件。
<add key="FolderToSaveTo" value="\APPDEV03\NEMStoPSIMS\" />
SharePointConnector.FolderToSaveTo = ConfigurationManager.AppSettings["FolderToSaveTo"];
try
{
ClientContext context = new ClientContext(sp_site_address);
context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication;
context.FormsAuthenticationLoginInfo = new
FormsAuthenticationLoginInfo(username, pwd);
List list = context.Web.Lists.GetByTitle(requests_list_name);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><RowLimit>100</RowLimit></View>";
ListItemCollection items = list.GetItems(query);
context.Load(list);
context.Load(items);
context.ExecuteQuery();
foreach (ListItem oListItem in items)
{
FileCollection Files = GetAttachments(context, list, oListItem);
foreach (Microsoft.SharePoint.Client.File f in Files)
{
Download(f.ServerRelativeUrl, FolderToSaveTo, context);
}
lstRequests.Add(Agreement);
}
}
catch (Exception ex)
{
throw ex;
}
public static FileCollection GetAttachments(ClientContext ctx, List list, ListItem item)
{
ctx.Load(list, l => l.RootFolder.ServerRelativeUrl);
ctx.Load(ctx.Site, s => s.Url);
ctx.ExecuteQuery();
Folder attFolder = ctx.Web.GetFolderByServerRelativeUrl(list.RootFolder.ServerRelativeUrl + "/Attachments/" + item.Id);
FileCollection files = attFolder.Files;
ctx.Load(files, fs => fs.Include(f => f.ServerRelativeUrl, f => f.Name, f => f.ServerRelativeUrl));
ctx.ExecuteQuery();
return files;
}
public static void Download(string serverFilePath, string destPath, ClientContext context)
{
using (FileInformation ffl = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, serverFilePath))
{
if (System.IO.Directory.Exists(destPath))
{
using (Stream destFile = System.IO.File.OpenWrite(destPath))
{
byte[] buffer = new byte[8 * 1024];
int len;
while ((len = ffl.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
destFile.Write(buffer, 0, len);
}
}
}
}
}
我在没有 Forms Auth 的情况下测试了这段代码。我将文件名作为变量传递给您的下载函数,并完全重写了流到文件部分,并对您的 SharePoint 调用进行了一些小调整。现在效果很好。
static void Main(string[] args)
{
using (ClientContext context = new ClientContext(sp_site_address))
{
context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication;
context.FormsAuthenticationLoginInfo = new FormsAuthenticationLoginInfo(username, pwd);
List list = context.Web.Lists.GetByTitle(requests_list_name);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><RowLimit>100</RowLimit></View>";
ListItemCollection items = list.GetItems(query);
context.Load(items);
context.ExecuteQuery();
foreach (ListItem oListItem in items)
{
FileCollection files = GetAttachments(context, list, oListItem);
foreach (Microsoft.SharePoint.Client.File f in files)
{
Download(f.ServerRelativeUrl, FolderToSaveTo, context, f.Name);
}
lstRequests.Add(Agreement);
}
}
}
public static FileCollection GetAttachments(ClientContext ctx, List list, ListItem item)
{
ctx.Load(list, l => l.RootFolder.ServerRelativeUrl);
ctx.Load(ctx.Site, s => s.Url);
ctx.ExecuteQuery();
Folder attFolder = ctx.Web.GetFolderByServerRelativeUrl(list.RootFolder.ServerRelativeUrl + "/Attachments/" + item.Id);
FileCollection files = attFolder.Files;
ctx.Load(files, fs => fs.Include(f => f.ServerRelativeUrl, f => f.Name, f => f.ServerRelativeUrl));
ctx.ExecuteQuery();
return files;
}
public static void Download(string serverFilePath, string destPath, ClientContext context, string filename)
{
using (FileInformation ffl = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, serverFilePath))
{
if (System.IO.Directory.Exists(destPath))
{
using (FileStream fileStream = System.IO.File.Create(destPath + "\" + filename))
{
using (MemoryStream stream = new MemoryStream())
{
ffl.Stream.CopyTo(stream);
stream.WriteTo(fileStream);
}
}
}
}
}
我有一个最终会 运行 作为控制台应用程序的控制台应用程序。我需要循环访问外部 Sharepoint 站点,查找所有新项目并查看是否有任何附件,如果有,我需要下载这些附件。
我能够查询列表,并且能够遍历附件以填充文件集合。
FolderToSaveTo 解析为“\\APPDEV03\NEMStoPSIMS\”并传递 if (System.IO.Directory.Exists(destPath)) 语句,但在下一行使用 (Stream destFile = System.IO.File.OpenWrite(destPath) ) 抛出 {"The filename, directory name, or volume label syntax is incorrect.\r\n"}
我可以导航到 \APPDEV03\NEMStoPSIMS\ 并且可以手动保存文件。
<add key="FolderToSaveTo" value="\APPDEV03\NEMStoPSIMS\" />
SharePointConnector.FolderToSaveTo = ConfigurationManager.AppSettings["FolderToSaveTo"];
try
{
ClientContext context = new ClientContext(sp_site_address);
context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication;
context.FormsAuthenticationLoginInfo = new
FormsAuthenticationLoginInfo(username, pwd);
List list = context.Web.Lists.GetByTitle(requests_list_name);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><RowLimit>100</RowLimit></View>";
ListItemCollection items = list.GetItems(query);
context.Load(list);
context.Load(items);
context.ExecuteQuery();
foreach (ListItem oListItem in items)
{
FileCollection Files = GetAttachments(context, list, oListItem);
foreach (Microsoft.SharePoint.Client.File f in Files)
{
Download(f.ServerRelativeUrl, FolderToSaveTo, context);
}
lstRequests.Add(Agreement);
}
}
catch (Exception ex)
{
throw ex;
}
public static FileCollection GetAttachments(ClientContext ctx, List list, ListItem item)
{
ctx.Load(list, l => l.RootFolder.ServerRelativeUrl);
ctx.Load(ctx.Site, s => s.Url);
ctx.ExecuteQuery();
Folder attFolder = ctx.Web.GetFolderByServerRelativeUrl(list.RootFolder.ServerRelativeUrl + "/Attachments/" + item.Id);
FileCollection files = attFolder.Files;
ctx.Load(files, fs => fs.Include(f => f.ServerRelativeUrl, f => f.Name, f => f.ServerRelativeUrl));
ctx.ExecuteQuery();
return files;
}
public static void Download(string serverFilePath, string destPath, ClientContext context)
{
using (FileInformation ffl = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, serverFilePath))
{
if (System.IO.Directory.Exists(destPath))
{
using (Stream destFile = System.IO.File.OpenWrite(destPath))
{
byte[] buffer = new byte[8 * 1024];
int len;
while ((len = ffl.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
destFile.Write(buffer, 0, len);
}
}
}
}
}
我在没有 Forms Auth 的情况下测试了这段代码。我将文件名作为变量传递给您的下载函数,并完全重写了流到文件部分,并对您的 SharePoint 调用进行了一些小调整。现在效果很好。
static void Main(string[] args)
{
using (ClientContext context = new ClientContext(sp_site_address))
{
context.AuthenticationMode = ClientAuthenticationMode.FormsAuthentication;
context.FormsAuthenticationLoginInfo = new FormsAuthenticationLoginInfo(username, pwd);
List list = context.Web.Lists.GetByTitle(requests_list_name);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View><RowLimit>100</RowLimit></View>";
ListItemCollection items = list.GetItems(query);
context.Load(items);
context.ExecuteQuery();
foreach (ListItem oListItem in items)
{
FileCollection files = GetAttachments(context, list, oListItem);
foreach (Microsoft.SharePoint.Client.File f in files)
{
Download(f.ServerRelativeUrl, FolderToSaveTo, context, f.Name);
}
lstRequests.Add(Agreement);
}
}
}
public static FileCollection GetAttachments(ClientContext ctx, List list, ListItem item)
{
ctx.Load(list, l => l.RootFolder.ServerRelativeUrl);
ctx.Load(ctx.Site, s => s.Url);
ctx.ExecuteQuery();
Folder attFolder = ctx.Web.GetFolderByServerRelativeUrl(list.RootFolder.ServerRelativeUrl + "/Attachments/" + item.Id);
FileCollection files = attFolder.Files;
ctx.Load(files, fs => fs.Include(f => f.ServerRelativeUrl, f => f.Name, f => f.ServerRelativeUrl));
ctx.ExecuteQuery();
return files;
}
public static void Download(string serverFilePath, string destPath, ClientContext context, string filename)
{
using (FileInformation ffl = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, serverFilePath))
{
if (System.IO.Directory.Exists(destPath))
{
using (FileStream fileStream = System.IO.File.Create(destPath + "\" + filename))
{
using (MemoryStream stream = new MemoryStream())
{
ffl.Stream.CopyTo(stream);
stream.WriteTo(fileStream);
}
}
}
}
}