ContentHash 未在 Azure Blob Storage v12 中计算
ContentHash not calculated in Azure Blob Storage v12
继续传奇,这是第一部分:
经过大量调试,根本原因似乎是 上传 blob 后未计算内容哈希值,因此 BlobContentInfo
或 BlobProperties
返回一个空内容哈希,我的整个流程基于从 Azure 接收哈希。
我发现这取决于我调用并上传到 azure 的 HttpRequest 流方法:
HttpRequest.GetBufferlessInputStream()
,没有计算content hash,即使我进入azure storage explorer,blob的ContentMD5也是空的
HttpRequest.InputStream()
一切正常。
你知道为什么会有这种不同的行为吗?你知道如何接收通过 GetBufferlessInputStream
方法接收的流的内容哈希吗?
因此代码流如下所示:
var stream = HttpContext.Current.Request.GetBufferlessInputStream(disableMaxRequestLength: true)
var container = _blobServiceClient.GetBlobContainerClient(containerName);
var blob = container.GetBlockBlobClient(blobPath);
BlobHttpHeaders blobHttpHeaders = null;
if (!string.IsNullOrWhiteSpace(fileContentType))
{
blobHttpHeaders = new BlobHttpHeaders()
{
ContentType = fileContentType,
};
}
// retry already configured of Azure Storage API
await blob.UploadAsync(stream, httpHeaders: blobHttpHeaders);
return await blob.GetPropertiesAsync();
在上面的代码片段中 ContentHash
没有被计算,但是如果我改变我从 http 请求中获取流的方式,下面的代码片段 ContentHash
被计算。
var stream = HttpContext.Current.Request.InputStream
P.S。我认为这很明显,但是对于旧的 sdk,内容哈希是为 GetBufferlessInputStream
方法
接收的流计算的
P.S2 您还可以在 github 上找到未解决的问题:https://github.com/Azure/azure-sdk-for-net/issues/14037
P.S3 添加代码片段
解决方法是当通过GetBufferlessInputStream()
方法获取流时,将其转换为MemoryStream
,然后上传MemoryStream
。然后它可以生成contenthash
。示例代码如下:
var stream111 = System.Web.HttpContext.Current.Request.GetBufferlessInputStream(disableMaxRequestLength: true);
//convert to memoryStream.
MemoryStream stream = new MemoryStream();
stream111.CopyTo(stream);
stream.Position = 0;
//other code
// retry already configured of Azure Storage API
await blob.UploadAsync(stream, httpHeaders: blobHttpHeaders);
不知道为什么,但根据我的调试,我可以看到在最新的 SDK 中使用方法 GetBufferlessInputStream()
时,在上传过程中,它实际上调用了 Put Block api in the backend. And in this api, MD5 hash is not stored with the blob(Refer to here 以获取详细信息。)。截图如下:
但是,当使用 InputStream
时,它会调用 Put Blob api。截图如下:
运行今天进入这个。从我的挖掘来看,这似乎是您用来上传的 Stream
类型的症状,它并不是真正的错误。为了为您的 blob 生成哈希(这是在客户端上传之前通过它的外观完成的),它需要读取流。这意味着它需要在生成哈希后将流的位置重置回 0(对于实际的上传过程)。这样做需要能够对流执行 Seek 操作。如果您的流不支持 Seek,那么看起来它不会生成哈希。
要解决此问题,请确保您提供的流支持 Seek (CanSeek
)。如果没有,则使用不同的 Stream/copy 您的数据到存在的流(例如 MemoryStream
)。另一种方法是让 Blob SDK 的内部为您执行此操作。
继续传奇,这是第一部分:
经过大量调试,根本原因似乎是 上传 blob 后未计算内容哈希值,因此 BlobContentInfo
或 BlobProperties
返回一个空内容哈希,我的整个流程基于从 Azure 接收哈希。
我发现这取决于我调用并上传到 azure 的 HttpRequest 流方法:
HttpRequest.GetBufferlessInputStream()
,没有计算content hash,即使我进入azure storage explorer,blob的ContentMD5也是空的
HttpRequest.InputStream()
一切正常。
你知道为什么会有这种不同的行为吗?你知道如何接收通过 GetBufferlessInputStream
方法接收的流的内容哈希吗?
因此代码流如下所示:
var stream = HttpContext.Current.Request.GetBufferlessInputStream(disableMaxRequestLength: true)
var container = _blobServiceClient.GetBlobContainerClient(containerName);
var blob = container.GetBlockBlobClient(blobPath);
BlobHttpHeaders blobHttpHeaders = null;
if (!string.IsNullOrWhiteSpace(fileContentType))
{
blobHttpHeaders = new BlobHttpHeaders()
{
ContentType = fileContentType,
};
}
// retry already configured of Azure Storage API
await blob.UploadAsync(stream, httpHeaders: blobHttpHeaders);
return await blob.GetPropertiesAsync();
在上面的代码片段中 ContentHash
没有被计算,但是如果我改变我从 http 请求中获取流的方式,下面的代码片段 ContentHash
被计算。
var stream = HttpContext.Current.Request.InputStream
P.S。我认为这很明显,但是对于旧的 sdk,内容哈希是为 GetBufferlessInputStream
方法
P.S2 您还可以在 github 上找到未解决的问题:https://github.com/Azure/azure-sdk-for-net/issues/14037
P.S3 添加代码片段
解决方法是当通过GetBufferlessInputStream()
方法获取流时,将其转换为MemoryStream
,然后上传MemoryStream
。然后它可以生成contenthash
。示例代码如下:
var stream111 = System.Web.HttpContext.Current.Request.GetBufferlessInputStream(disableMaxRequestLength: true);
//convert to memoryStream.
MemoryStream stream = new MemoryStream();
stream111.CopyTo(stream);
stream.Position = 0;
//other code
// retry already configured of Azure Storage API
await blob.UploadAsync(stream, httpHeaders: blobHttpHeaders);
不知道为什么,但根据我的调试,我可以看到在最新的 SDK 中使用方法 GetBufferlessInputStream()
时,在上传过程中,它实际上调用了 Put Block api in the backend. And in this api, MD5 hash is not stored with the blob(Refer to here 以获取详细信息。)。截图如下:
但是,当使用 InputStream
时,它会调用 Put Blob api。截图如下:
运行今天进入这个。从我的挖掘来看,这似乎是您用来上传的 Stream
类型的症状,它并不是真正的错误。为了为您的 blob 生成哈希(这是在客户端上传之前通过它的外观完成的),它需要读取流。这意味着它需要在生成哈希后将流的位置重置回 0(对于实际的上传过程)。这样做需要能够对流执行 Seek 操作。如果您的流不支持 Seek,那么看起来它不会生成哈希。
要解决此问题,请确保您提供的流支持 Seek (CanSeek
)。如果没有,则使用不同的 Stream/copy 您的数据到存在的流(例如 MemoryStream
)。另一种方法是让 Blob SDK 的内部为您执行此操作。