【发布时间】:2011-05-04 14:30:55
【问题描述】:
我正在构建一个应用程序,该应用程序需要允许用户将大图像(最大约 100 MB)上传到 Windows Azure Blob 存储服务。在阅读了 Rob Gillen's excellent article 关于 Windows Azure 文件上传优化的内容后,我借用了他的方法来并行上传文件块,在 Parallel.For 循环中使用 CloudBlockBlob.PutBlock() 方法(代码可用 here)。
我遇到的问题是,每当我尝试上传文件时,我都会从 storage client 收到“InvalidMd5”异常。怀疑问题可能出在开发存储中,我还尝试对我的实时 Azure 存储帐户运行代码,但我得到了同样的错误。查看Fiddler 的流量,我看到“Content-MD5”标头设置为有效的 MD5 哈希。错误描述说“请求中指定的 MD5 值无效。MD5 值必须是 128 位和 Base64 编码的。”,但据我所知,我看到的值在 Fiddler 中发送是有效的(例如 a91c588092cedbdb1b82c2d3786fd509)。
这是我用于计算哈希的代码(由 Rob Gillen 提供):
public static string GetMD5HashFromStream(byte[] data)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(data);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
这是对 PutBlock() 的实际调用:
blob.PutBlock(transferDetails[j].BlockId, new MemoryStream(buff), blockHash, options);
我也尝试像这样传递哈希:
Convert.ToBase64String(Encoding.UTF8.GetBytes(blockHash))
但结果是一样的——“InvalidMd5”错误:(
使用 base64 编码(例如 YTkxYzU4ODA5MmNlZGJkYjFiODJjMmQzNzg2ZmQ1MDk=)传递给 PutBlock() 的 MD5 哈希值(例如 a91c588092cedbdb1b82c2d3786fd509)似乎没有什么区别。
Rob 的code 显然对他有用,我真的不知道是什么导致了我的问题。我对 Rob 的代码所做的唯一更改是更改 ParallelUpload() 扩展方法以采用 Stream 而不是文件名,并根据上传文件的大小动态确定块大小。
如果有人知道如何解决这个问题,请告诉我!我将不胜感激!我已经为此苦苦挣扎了两天。
【问题讨论】: