尝试使用 REST API 将大型二进制文件添加到 Azure DevOps 时,我们似乎遇到了限制。相同的文件签入使用旧的 SOAP API 可以正常工作,也可以使用 TFVC CLI (tf.exe)。但是我们有一个用例,我们需要偶尔从没有安装 VS 的机器上以编程方式签入大文件。我们正在尝试将我们的应用程序从旧的 SOAP API 迁移到 REST API,因为我们正在迁移到不支持 SOAP API 的 .NET Core。
对带有大(> 约 19 MB)文件的 /_apis/tfvc/changesets(创建变更集)API 的 POST 会导致:
HTTP 400:错误请求
此问题已在 Azure DevOps .NET Samples github repo 上多次报告,但这不是该问题的正确论坛,因此尚未在那里得到解答。
- https://github.com/microsoft/azure-devops-dotnet-samples/issues/176
- https://github.com/microsoft/azure-devops-dotnet-samples/issues/104
我们如何使用 REST API 在 TFVC 中创建大文件?
更新 2020-01-13
这是我们用来演示问题的示例控制台应用程序:
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Program
{
internal static async Task Main(string[] args)
{
var orgUrl = new Uri(args[0]);
string serverPath = args[1];
string localPath = args[2];
string contentType = args[3];
string pat = args[4];
var changes = new List<TfvcChange>()
{
new TfvcChange()
{
ChangeType = VersionControlChangeType.Add,
Item = new TfvcItem()
{
Path = serverPath,
ContentMetadata = new FileContentMetadata()
{
Encoding = Encoding.UTF8.WindowsCodePage,
ContentType = contentType,
}
},
NewContent = new ItemContent()
{
Content = Convert.ToBase64String(File.ReadAllBytes(localPath)),
ContentType = ItemContentType.Base64Encoded
}
}
};
var changeset = new TfvcChangeset()
{
Changes = changes,
Comment = $"Added {serverPath} from {localPath}"
};
var connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, pat));
var tfvcClient = connection.GetClient<TfvcHttpClient>();
await tfvcClient.CreateChangesetAsync(changeset);
}
}
}
对 Azure DevOps TFVC 存储库运行带有 ~50MB zip 文件的此控制台应用程序会导致VssServiceResponseException
(带有 inner ArgumentException
)消息为:The maximum request size of 26214400 bytes was exceeded。
2020-01-14 更新
- 在我的示例代码中发送 TFVC 请求之前添加了文件大小和 base64 内容长度的显示。
- 更正了我对文件大小限制的观察。
- 更正了 Azure DevOps 返回的错误代码(400,而不是 413)。
最初我说限制是 13 MB 左右。这是基于我看到的文件 > 20 MB 的失败、文件 < 大约 10 MB 的成功以及链接的 github 问题中描述的限制。
我自己进行了更多测试,并缩小了大约 19,200 KB 作为实际限制。根据指示 26,214,400 字节限制的错误消息,这似乎是正确的。一个 19 MB 的 base-64 编码文件将扩展到大约 26 MB。
我还在最近的测试中注意到,在使用 Fiddler 进行监视时,Azure DevOps 返回了 400 状态代码(而不是 413)。我的笔记表明在过去的某个时候观察到了 413 Request Entity Too Large。也许这与旧版本的 Azure DevOps 服务器有关?无论如何,我们现在看到的错误是 400 Bad Request。
这是 Fiddler 为请求标头显示的内容:
POST /<...REMOVED...>/_apis/tfvc/changesets HTTP/1.1
Host: dev.azure.com
Accept: application/json; api-version=5.1
User-Agent: VSServices/16.153.29226.1 (NetStandard; Microsoft Windows 10.0.18363)
X-VSS-E2EID: 6444f0b5-57e0-45da-bd86-a4c62d8a1794
Accept-Language: en-US
X-TFS-FedAuthRedirect: Suppress
X-TFS-Session: 9f8e8272-db48-4e93-b9b0-717937244aff
Expect: 100-continue
Authorization: Basic <...REMOVED...>
Accept-Encoding: gzip
Content-Type: application/json; charset=utf-8; api-version=5.1
Content-Length: 26324162
原始回应:
HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 206
Content-Type: application/json; charset=utf-8
Expires: -1
P3P: CP="CAO DSP COR ADMa DEV CONo TELo CUR PSA PSD TAI IVDo OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR LOC CNT"
X-TFS-ProcessId: 7611d69f-e722-4108-8050-e55a61b1cbb4
Strict-Transport-Security: max-age=31536000; includeSubDomains
ActivityId: 15e046e5-3788-4fdb-896a-7d0482121ddd
X-TFS-Session: 9f8e8272-db48-4e93-b9b0-717937244aff
X-VSS-E2EID: 6444f0b5-57e0-45da-bd86-a4c62d8a1794
X-VSS-UserData: <...REMOVED...>
X-FRAME-OPTIONS: SAMEORIGIN
Request-Context: appId=cid-v1:e3d45cd2-3b08-46bc-b297-cda72fdc1dc1
Access-Control-Expose-Headers: Request-Context
X-Content-Type-Options: nosniff
X-MSEdge-Ref: Ref A: 7E9E95F5497946AC87D75EF3AAD06676 Ref B: CHGEDGE1521 Ref C: 2020-01-14T14:01:59Z
Date: Tue, 14 Jan 2020 14:02:00 GMT
{"$id":"1","innerException":null,"message":"The maximum request size of 26214400 bytes was exceeded.","typeName":"System.ArgumentException, mscorlib","typeKey":"ArgumentException","errorCode":0,"eventId":0}