Azure Block Blob:提交先前提交的块时,“指定的块列表无效”

问题描述 投票:1回答:1

使用Azure.Storage.Blob .NET SDK v12,我尝试将其附加到块Blob。根据各种文档,似乎执行此操作的方法是将以前提交的块ID列表连同新的块ID一起提交。我确保块ID的长度都相同。但是,当我尝试提交已经提交的块ID时,出现“ 400:指定的块列表无效”错误。

这里有一些简化的代码说明了问题:

// Create a blob container and a new block blob
string connectionString = @"...";
BlobServiceClient serviceClient = new BlobServiceClient(connectionString);
string containerName = Guid.NewGuid().ToString();
BlobContainerClient containerClient = serviceClient.CreateBlobContainer(containerName);
BlockBlobClient blobClient = containerClient.GetBlockBlobClient("some-blob");

// Stage and commit a block containing some dummy data
byte[] dummyData = new byte[1024];
byte[] firstBlockID = Encoding.UTF8.GetBytes("0");
string firstIDBase64 = Convert.ToBase64String(firstBlockID); // "MA=="
var stageResponse = blobClient.StageBlock(firstIDBase64, new MemoryStream(dummyData));
var responseInfo = stageResponse.GetRawResponse(); // 201: Created
var contentResponse = blobClient.CommitBlockList(new[] { firstIDBase64 });
responseInfo = contentResponse.GetRawResponse(); // 201: Created

// Stage a second block
byte[] secondBlockID = Encoding.UTF8.GetBytes("1");
string secondIDBase64 = Convert.ToBase64String(secondBlockID); // "MQ=="
stageResponse = blobClient.StageBlock(secondIDBase64, new MemoryStream(dummyData));
responseInfo = stageResponse.GetRawResponse(); // 201: Created

// Sanity check: 
// Viewing the block list in the debugger shows both the committed block ID 
// "MA==" and uncommitted block ID "MQ==", as expected.
BlockList blockList = blobClient.GetBlockList(BlockListTypes.All).Value;

// Commit both the previously committed block. and the new uncommitted one.
// This results in the the error:
//    Status: 400(The specified block list is invalid.)
//    ErrorCode: InvalidBlockList
blobClient.CommitBlockList(new[] { firstIDBase64, secondIDBase64 });
c# .net azure-storage-blobs
1个回答
1
投票

很好的问题!我认为问题出在CommitBlockList方法的实现方式上。我在Fiddler中检查了请求/响应,这就是发送到存储服务的内容:

<BlockList>
    <Uncommitted>MA==</Uncommitted>
    <Uncommitted>MQ==</Uncommitted>
</BlockList>

[如果您注意到,即使已提交具有MA==块ID的块,SDK仍将其作为Uncommitted发送,这会引起问题。

然后,我查看了此方法here的文档,这是我注意到的here参数的内容:

指定未提交 Base64编码的块ID表示Blob服务应仅在未提交的阻止列表中搜索命名块。如果在未提交的阻止列表中找不到该阻止,它不会被写入blob的一部分,并且RequestFailedException将被抛出。

因为具有base64BlockIds块ID的块已经提交,并且您将其作为未提交的块发送,所以Storage Service引发异常。

恕我直言,该方法的实现不符合MA== REST API操作。考虑到完全有可能使用REST API这样做,应该修改SDK以考虑这种情况。我建议为此在Put Block List上打开一个问题。

© www.soinside.com 2019 - 2024. All rights reserved.