问题描述
使用Azure.Storage.Blob .NET SDK v12,我尝试将其附加到块Blob.根据各种文档,似乎执行此操作的方法是提交先前提交的块ID以及新块ID的列表.我确保块ID的长度都相同.但是,当我尝试提交已经提交的阻止ID时,会收到"400:指定的阻止列表无效"错误.
Using the Azure.Storage.Blob .NET SDK v12, I'm trying to append to a block blob. Based on various documentation, it seems the way to do this is to commit a list of previously committed block IDs along with new block IDs. I've made sure that the block IDs are all the same length. But when I try to commit a block ID that has already been committed, I get a "400: The specified block list is invalid" error.
下面是一些简化的代码来说明问题所在:
Here is some simplified code which illustrates the problem:
// 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 });
推荐答案
好问题!我认为问题出在 CommitBlockList
方法的实现方式上.我在Fiddler中检查了请求/响应,这就是发送到存储服务的内容:
Great question! I believe the issue is with the way CommitBlockList
method is implemented. I checked the request/response in Fiddler and this is what is being sent to Storage service:
<BlockList>
<Uncommitted>MA==</Uncommitted>
<Uncommitted>MQ==</Uncommitted>
</BlockList>
如果您注意到,即使已提交具有 MA ==
块ID的块,SDK仍会以 Uncommitted
的形式发送它,这是造成问题的原因.
If you notice, even though block with MA==
block id has been committed, SDK is still sending it as Uncommitted
and that's causing the problem.
然后,我查看了此方法的文档 这里的,而这正是我注意到了 base64BlockIds 的参数:
Then I looked at the documentation of this method here
, and this is what I noticed for base64BlockIds
parameter:
因为具有 MA ==
块ID的块已经提交,并且您将其作为未提交的块发送,所以Storage Service引发异常.
Because the block with MA==
block id is already committed and you're sending it as uncommitted block, Storage Service is throwing the exception.
恕我直言,该方法的实现不符合 放入阻止列表
REST API操作.考虑到完全有可能使用REST API这样做,应该修改SDK以考虑这种情况.我建议在 SDK存储库
.
IMHO, the method implementation is not in compliance with Put Block List
REST API operation. SDK should be modified to consider this scenario considering it is entirely possible to do so using REST API. I would recommend opening up an issue on SDK Repository
for this.
这篇关于Azure块Blob:“指定的块列表无效"提交先前提交的块时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!