如何在csom上下文中获取重试后标头?

时间:2018-08-07 15:33:40

标签: powershell office365 onedrive sharepoint-online csom

我正在使用PowerShell和CSOM来镜像Sharepoint Online和OneDrive网站及其所有文件。

因此,在下载了几千个文件/几个小时后,按预期方式引发了“操作已超时”异常。这是由于微软的限制。

为防止超时,我使用CSOM上下文的RequestTimeOut参数,并进行增量重试,并将ExecuteQuery()调用的数量限制为每秒2,还装饰了CSOM调用。但是,这还不够。

失败呼叫的http响应标头应该包含“ Retry-After”行,我想用它来计时重试时间。

在Microsoft.SharePoint.Client.ClientContext的ExecuteQuery()或[Microsoft.SharePoint.Client.File] :: OpenBinaryDirect()期间发生异常。

以下是一些简化的代码摘录:

$Context = New-Object Microsoft.SharePoint.Client.ClientContext($WebURL)
$Context.Credentials = $spoCredential
$Context.RequestTimeout = 60000; # 1 min
$Context.add_ExecutingWebRequest({
    param($Source, $EventArgs)
    $request = $EventArgs.WebRequestExecutor.WebRequest
    $request.UserAgent = "XXX|CsomPs|MyScript/1.0"
})
$Web = $Context.Web
$Context.Load($Web)
$Context.ExecuteQuery()

所有这些都可以很好地工作,直到引发“操作已超时”异常。说,示例的$ Context.ExecuteQuery()引发异常。

如何在CSOM powershell脚本中访问http响应,尤其是http响应标头,甚至更特别是Retry-After标头?

谢谢!

2 个答案:

答案 0 :(得分:0)

首先,您无法访问和自定义HTTP响应。这是由SharePoint Online端处理的。

第二,您应该避免在SharePoint Online中受到限制或阻止。 Microsoft没有确切的限制,因此最好减少每个请求的操作数量或减少呼叫频率 这是在CSOM中装饰流量的代码

// Get access to source site
using (var ctx = new ClientContext("https://contoso.sharepoint.com/sites/team"))
{
//Provide account and pwd for connecting to SharePoint Online
var passWord = new SecureString();
foreach (char c in pwd.ToCharArray()) passWord.AppendChar(c);
ctx.Credentials = new SharePointOnlineCredentials("contoso@contoso.onmicrosoft.com", 
passWord);

// Add our User Agent information
ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e)
{
    e.WebRequestExecutor.WebRequest.UserAgent = "NONISV|Contoso|GovernanceCheck/1.0";
};

// Normal CSOM Call with custom User-Agent information
Web site = ctx.Web;
ctx.Load(site);
ctx.ExecuteQuery();
}

如果这没有帮助,则可以CoreThrottling跟进此演示。

答案 1 :(得分:0)

您可以通过这种方式从失败的CSOM响应中访问标头。这可以与Powershell互换。

try {
    context.ExecuteQuery();
}
catch(WebException wex) {
    var response = wex.Response as HttpWebResponse;
    if (response != null && (response.StatusCode == (HttpStatusCode)429 || response.StatusCode == (HttpStatusCode)503))
    {
        // Reference the headers in the throttled / failed response
        response.Headers
    }
}

完整的MS代码示例(.RetryQuery的搜索页):https://docs.microsoft.com/en-us/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online

经过大量的调整后,我从未真正看到Retry-After值恢复为120(秒)以外的任何值。