我遇到了同样的错误。在我更新到 2.0 之前,这段代码曾经有效:
var sharedAccessPolicy = new SharedAccessBlobPolicy
{
SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-10),
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(30),
Permissions = SharedAccessBlobPermissions.Read
};
var sharedAccessSignature = _blockblob.GetSharedAccessSignature(sharedAccessPolicy);
return _blockblob.Uri.AbsoluteUri + sharedAccessSignature;
我得到了 uri:
http://127.0.0.1:10000/devstoreaccount1/original/c04d2a1c-980b-42c5-b76e-b71185f027b6.jpg?sv=2012-02-12&st=2012-11-20T08%3A30%3A24Z&se=2012-11-20T09%3A10%3A24Z&sr=b&sp=r&sig=9%2BVg6mSGqyrfr5rPlNJ6GSv%2BHN3J9k%2FWFRLYmx3xCvQ%3D
更新,已解决:
在上面的代码中,我有 blockBlob。这是在构造函数中设置的
var blobClient = account.CreateCloudBlobClient();
var container = blobClient.GetContainerReference(containerName);
CloudBlockBlob _blockblob = container.GetBlockBlobReference(fileName);
将最后一行(按照clausndk的建议)更改为
ICloudBlob _test = container.GetBlobReferenceFromServer(fileName);
解决了问题,因为在 _test 上调用 GetSharedAccessSignature 会产生不同的(有效)签名。
查看 Azure 存储的源代码并在我的应用程序上使用调试器,我找到了问题的原因。在我的代码中,我有一个带有尾部斜杠(original/)的containerName。除了 GetSharedAccessSignature 之外,这不是问题。这里,额外的斜杠弄乱了 canonicalName(在给出双斜杠的代码中添加了一个斜杠),这使得签名无效。 GetBlobReferenceFromServer 起作用的原因是它向服务器(通过 REST API)请求 blob,并且生成的 CloudBlockBlob 已删除斜杠。
在我的代码中,我删除了尾部斜杠,但 Sandrino Di Mattia 在容器名称上使用 .Trim('/') 的解决方案也有效。我认为这比使用 GetBlobReferenceFromServer 更好,因为它会导致额外的服务器调用。
希望 CloudBlockBlobBase 中 GetCanonicalName 的实现将被更改以在将来处理尾部斜杠(我已经创建了一个问题)GitHub https://github.com/WindowsAzure/azure-sdk-for-net/issues/131为此)但目前这种“解决方法”有效。