如何从SharePoint中的文档下载版本历史记录中的文档

如何从SharePoint中的文档下载版本历史记录中的文档,sharepoint,dynamics-crm,Sharepoint,Dynamics Crm,我想从SharePoint中文件的“版本历史记录”下载所有文档 我需要通过接口或C#代码获取文档 我也尝试了下面的API URL,但我得到了一个错误 https://XXXX.sharepoint.com/_api/Web/GetFileByServerRelativeUrl('fileURL')/Versions 我想你不可能一次下载所有的版本。您必须发送附加在括号内的versionid,如versions(),才能获取特定项目 http://<site url>/_api/we

我想从SharePoint中文件的“版本历史记录”下载所有文档

我需要通过接口或C#代码获取文档

我也尝试了下面的API URL,但我得到了一个错误

https://XXXX.sharepoint.com/_api/Web/GetFileByServerRelativeUrl('fileURL')/Versions
我想你不可能一次下载所有的版本。您必须发送附加在括号内的
versionid
,如
versions()
,才能获取特定项目

http://<site url>/_api/web/getfilebyserverrelativeurl('/<folder name>/<file name>')/versions(<version id>)
http:///_api/web/getfilebyserverrelativeurl(“//”)/versions()

如果需要次要版本,请正确设置预期url。

确保您使用的是最新版本的SharePoint Online CSOM,或至少是2017年9月之后的版本

您可以从Nuget获得最新的CSOM版本,并将其添加到您的项目中

完成后,您可以使用下面提到的代码下载文件的版本。根据您的环境、信誉和文件名进行修改:

var siteUrl = "https://XXXX.sharepoint.com";
var userName = "user.name@tenantname.onmicrosoft.com";
var password = "password";

using (ClientContext context = new ClientContext(siteUrl))
{
    SecureString securePassword = new SecureString();
    foreach (char c in password.ToCharArray())
    {
        securePassword.AppendChar(c);
    }

    context.AuthenticationMode = ClientAuthenticationMode.Default;
    context.Credentials = new SharePointOnlineCredentials(userName, securePassword);

    var file = context.Web.GetFileByServerRelativeUrl(siteUrl + "/Documents/test.docx");
    var fileVersions = file.Versions; 
    context.Load(file); 
    context.Load(fileVersions);
    context.ExecuteQuery();

    int index = 0;
    foreach (var version in fileVersions)
    {    
       var str = version.OpenBinaryStream();
       context.ExecuteQuery();

       string filename = string.Format("c:\\Downloads\\test-{0}.docx", index);
       using (var fileStream = new FileStream(filename, FileMode.OpenOrCreate))
       {
         str.Value.CopyTo(fileStream);
       }
       index++;     
    }

}

参考-

以下代码供您参考

string _SharePointSiteURL = @"https://lz.sharepoint.com/sites/lz";

var _SharePointSiteUser = "lz@lz.onmicrosoft.com";
var password = "Password";

var localPath = @"c:\test\";

var filePath="Shared Documents/ABC/Test.pdf";

var securePassword = new SecureString();

foreach (char c in password)
{
    securePassword.AppendChar(c);
}

using (var clientContext = new ClientContext(_SharePointSiteURL))
{
    var onlineCredentials = new SharePointOnlineCredentials(_SharePointSiteUser, securePassword);
    clientContext.RequestTimeout = 10000000;
    clientContext.Credentials = onlineCredentials;
    Web web = clientContext.Web;
    clientContext.Load(web, website => website.ServerRelativeUrl, website => website.Url);
    clientContext.ExecuteQuery();

    var spFile = clientContext.Web.GetFileByServerRelativeUrl((web.ServerRelativeUrl.EndsWith("/") ? web.ServerRelativeUrl : web.ServerRelativeUrl + "/") + filePath);
    clientContext.Load(spFile);
    FileVersionCollection versions = spFile.Versions;
    clientContext.Load(versions);
    var oldVersions = clientContext.LoadQuery(versions.Where(v => v != null));
    clientContext.ExecuteQuery();
    if (oldVersions != null)
    {
        foreach (Microsoft.SharePoint.Client.FileVersion _version in oldVersions)
        {

            if (!Directory.Exists(localPath))
            {
                Directory.CreateDirectory(localPath);
            }

            using (var wc = new System.Net.WebClient())
            {                       
                wc.Credentials = onlineCredentials;
                wc.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
                wc.Headers["User-Agent"] = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; MDDC)";
                wc.DownloadFile(web.Url + "/" + _version.Url, localPath+"Test.pdf");
            }   
        }
    }
}

此答案适用于可能正在寻找Powershell CSOM脚本的其他人,该脚本将下载当前文档和版本历史记录

诚然,我是一个Powershell新手,我很难找到一个可以从SharePoint下载所有当前文件及其版本的脚本。访问这些版本被证明是一个挑战,因为我尝试过的各种脚本要么(404)找不到,要么(403)被禁止。我能够拼凑一个CSOM函数,我从另一个脚本调用它,该脚本从指定的库/列表下载所有当前版本。我无法发布我的整个解决方案,因为原始脚本不是我的。你可以在这里找到它:

在上面站点的下载AllFileFromLibrary函数中,我添加了GetFileVersions作为Foreach($FilesColl中的File)循环的最后一条语句

正如我所说,我是Powershell的新手,因此我确信可以对该函数进行一些改进,但它是有效的

Function GetFileVersions
{
#Get versions of specific document from library
$fileVersions = $file.Versions;
$ctx.Load($fileVersions);
$ctx.ExecuteQuery();
$vcount = $fileversions.count;

If ($vcount -ne “0” ) { 
# Download all versions of specific file as individual docs
$fname,$fext = $file.name.split('.');   # Separate filename and extension to different variables
 foreach ($fversion in $fileVersions) {
    $str = $fversion.OpenBinaryStream(); 
    $ctx.ExecuteQuery(); 
    $dtime = $fversion.created.ToString(“u”) -replace “:”,””;   # Convert date/time created to formatted string and replace semicolons in the time with blank
    $filename =$localfolder + “\” + $fname + “~” + $dtime + “.” + $fext ; # Compose the filename as the target folder, file name + ~+ datetime created.fileextension (i.e. book~2019-02-12 153659Z.xlsx)
    $fs = New-Object IO.FileStream $filename ,'Create','Write','Read'; 
    $str.Value.CopyTo($fs); 

    #To use the Write-Log function below, see the script at https://gallery.technet.microsoft.com/scriptcenter/Write-Log-PowerShell-999c32d0

   #$vmessage = $filename + “*” + $fversion.versionlabel;  # Message to write to the log file 
  #Write-Log $vmessage;

    $fs.Close();
   }
        if ($fs.isdisposable) {$fs.Dispose();}  
}
}

我有一个我开发的迁移工具的工作解决方案。必要的是将文件和旧版本从SharePoint环境迁移到另一个环境

要下载旧版本,请执行以下操作:

public byte[] DownloadFile(string url, bool isHistory = false)
{
    bool isSharepointOnline = (SPCurrentContext.Credentials is SharePointOnlineCredentials);
    HttpResponseMessage response = null;
    byte[] buffer = null;

    if (!isHistory)
    {
        using (FileInformation fileInfo = File.OpenBinaryDirect(SPCurrentContext, url))
        using (IO.MemoryStream memory = new IO.MemoryStream())
        {
            fileInfo.Stream.CopyTo(memory);
            buffer = memory.ToArray();
        }
    }
    else if (isSharepointOnline)
    {
        using (WebClient httpClient = new WebClient())
        {
            httpClient.Credentials = SPCurrentContext.Credentials;
            httpClient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
            httpClient.Headers["User-Agent"] = this.NONISV; // This is the TRICK!!! 

            buffer = httpClient.DownloadData(string.Concat(SPCurrentContext.Url, url));
        }
    }
    else
    {
        using (HttpClientHandler httpHandler = new HttpClientHandler() { Credentials = SPCurrentContext.Credentials })
        using (HttpClient client = new HttpClient(httpHandler))
        {
            response = client.GetAsync(string.Concat(SPCurrentContext.Url, url)).Result;

            response.EnsureSuccessStatusCode();

            response.Content.LoadIntoBufferAsync().Wait();

            buffer = response.Content.ReadAsByteArrayAsync().Result;
        }
    }

    return buffer;
}
说明:

由于您有文件URL(file.ServerRelativeUrl和FileVersion.URL),因此此方法可以很好地下载文件的当前版本或旧版本。然后,当您尝试从“SharePoint Online”下载文件版本时,就像在“SP On Premises”中一样,您将收到403 HTTP错误

当您放置一些用户代理和基于X-FORMS_的_AUTH_接受头时,解决方案开始工作。但是当然,由于429 HTTP错误,您将收到一个超时错误。 若要绕过,您必须将程序注册为SharePoint加载项

要执行此操作,请转到:

{您的sharepoint online根url}/_layouts/15/AppRegNew.aspx

并生成外接程序注册(有关说明和更多信息,请参阅和)

一旦获得它,就可以使用NONISV |{Your Company Name}|{Your Add-In Name}/1.0作为用户代理HTTP头。祝你好运

将其更改为“GetFileByUrl”,效果非常好,您还可以使用verion.VersionLabel来存储名称为version的文件