将SharePoint文件夹和内容移动到同一文档库中的不同位置

我正在寻找一种方法,使用SharePoint 2010客户端对象模型(C#)将文件夹及其所有内容移动到同一库中的其他位置。

例如,我们有一个项目的文件夹(比如12345),它的URL是

http://sharepoint/site/library/2012/12345 

2012年代表一年。 我想以编程方式将12345文件夹移动到另一年,比如2014年可能已存在但可能不存在。

我一直在搜索,但我得到的解决方案似乎非常复杂,并且与将文件夹移动到不同的网站集有关,我希望因为它在同一个库中可能有一个更简单的解决方案? 我的一个想法是依靠Explorer View而不是CSOM?

非常感谢!

SharePoint CSOM API中没有用于将文件夹从一个位置移动到另一个位置的内置方法。

以下类表示如何将文件从源文件夹移动到目标文件夹:

 public static class FolderExtensions { public static void MoveFilesTo(this Folder folder, string folderUrl) { var ctx = (ClientContext)folder.Context; if (!ctx.Web.IsPropertyAvailable("ServerRelativeUrl")) { ctx.Load(ctx.Web, w => w.ServerRelativeUrl); } ctx.Load(folder, f => f.Files, f => f.ServerRelativeUrl, f => f.Folders); ctx.ExecuteQuery(); //Ensure target folder exists EnsureFolder(ctx.Web.RootFolder, folderUrl.Replace(ctx.Web.ServerRelativeUrl, string.Empty)); foreach (var file in folder.Files) { var targetFileUrl = file.ServerRelativeUrl.Replace(folder.ServerRelativeUrl, folderUrl); file.MoveTo(targetFileUrl, MoveOperations.Overwrite); } ctx.ExecuteQuery(); foreach (var subFolder in folder.Folders) { var targetFolderUrl = subFolder.ServerRelativeUrl.Replace(folder.ServerRelativeUrl,folderUrl); subFolder.MoveFilesTo(targetFolderUrl); } } public static Folder EnsureFolder(Folder parentFolder, string folderUrl) { var ctx = parentFolder.Context; var folderNames = folderUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); var folderName = folderNames[0]; var folder = parentFolder.Folders.Add(folderName); ctx.Load(folder); ctx.ExecuteQuery(); if (folderNames.Length > 1) { var subFolderUrl = string.Join("/", folderNames, 1, folderNames.Length - 1); return EnsureFolder(folder, subFolderUrl); } return folder; } } 

关键点:

  • 允许确保目标文件夹是否存在
  • 如果是嵌套文件夹,则在移动文件时会保留其结构

用法

 var srcFolderUrl = "/news/pages"; var destFolderUrl = "/news/archive/pages"; using (var ctx = new ClientContext(url)) { var sourceFolder = ctx.Web.GetFolderByServerRelativeUrl(srcFolderUrl); sourceFolder.MoveFilesTo(destFolderUrl); sourceFolder.DeleteObject(); // delete source folder if nessesary ctx.ExecuteQuery(); } 

以防有人需要将其翻译成PnP PowerShell。 它不是经过测试,但对我有用。 版本和元数据也在同一个库中移动。

 $list = Get-PnPList -Identity Documents $web = $list.ParentWeb $folder = Ensure-PnPFolder -Web $list.ParentWeb -SiteRelativePath "Shared Documents/MoveTo" $tofolder = Ensure-PnPFolder -Web $list.ParentWeb -SiteRelativePath "Shared Documents/MoveTwo" function MoveFolder { [cmdletbinding()] Param ( $web, $fromFolder, $toFolder ) $fromFolder.Context.Load($fromFolder.Files) $fromFolder.Context.Load($fromFolder.Folders) $fromFolder.Context.ExecuteQuery() foreach ($file in $fromFolder.Files) { $targetFileUrl = $file.ServerRelativeUrl.Replace($fromFolder.ServerRelativeUrl, $toFolder.ServerRelativeUrl); $file.MoveTo($targetFileUrl, [Microsoft.SharePoint.Client.MoveOperations]::Overwrite); } $fromFolder.Context.ExecuteQuery(); foreach ($subFolder in $fromFolder.Folders) { $targetFolderUrl = $subFolder.ServerRelativeUrl.Replace($fromFolder.ServerRelativeUrl, $toFolder.ServerRelativeUrl); $targetFolderRelativePath = $targetFolderUrl.SubString($web.RootFolder.ServerRelativeUrl.Length) $tofolder = Ensure-PnPFolder -Web $list.ParentWeb -SiteRelativePath $targetFolderRelativePath MoveFolder -Web $web -fromFolder $subFolder -toFolder $tofolder } } $web.Context.Load($web.RootFolder) $web.Context.ExecuteQuery() MoveFolder -Web $web -fromFolder $folder -toFolder $tofolder $folder.DeleteObject() $web.Context.ExecuteQuery()