fp0*_*p0n 4 azure azure-storage azure-storage-blobs azure-sdk-.net
我正在将ClickOnce安装从常规Web服务器移动到Azure Blob存储,并且某些文件存在问题.文件名包含[ ]并CloudBlob.UploadFile失败,但有异常:
Microsoft.WindowsAzure.Storageclient.StorageException:
访问blob存储时出错:服务器无法验证请求.确保正确形成Authorization标头的值,包括签名.
代码已经使用了一段时间,并且只[ ]在名称中的文件上失败,因此我不认为它是"身份验证失败".在这种特殊情况下,这是在循环中上传的第七个文件.我在MSDN上发现了这个关于有效文件名的链接,这在堆栈溢出时发现了URL和引用中的方括号问题UrlEncode.我在电话中加入UrlEncode,但没有帮助.该容器是使用公共访问创建的,因为我们使用它来支持客户下载我们的软件.我们一直在另一个容器中托管"测试"安装,并且没有访问它的权限问题.
我可以上传没有更改名称的文件,然后使用newdesic的Azure存储资源管理器工具重命名该文件以添加"路径",那么我正在做什么呢?
我看到你正在使用1.7 SDK.这是SDK的一个小编码问题,也存在于v2.0中.让我们看看发生了什么.
account.CreateCloudBlobClient()
.GetContainerReference("temp")
.GetBlobReference("abc[]def.txt")
.UploadFile("myfile.txt");
Run Code Online (Sandbox Code Playgroud)
如果不对blob名称进行编码,则最终会向以下URL发出请求,从而导致身份验证异常:
这是因为SDK在Uri.EscapeUriString内部使用来对您的字符串进行编码,但这并没有考虑方括号.
然后你会期望以下方法来做到这一点:
account.CreateCloudBlobClient()
.GetContainerReference("temp")
.GetBlobReference(HttpUtility.UrlEncode("abc[]def.txt"))
.UploadFile("myfile.txt");
Run Code Online (Sandbox Code Playgroud)
这里的问题是你最终会得到这个网址:
http://account.blob.core.windows.net/temp/abc%255b%255ddef.txt
那么这里发生了什么?调用HttpUtility.UrlEncode将abc [] def.txt转换为abc%5B%5Ddef.txt,这是正确的.但在内部,SDK将再次编码此字符串,导致abc%255b%255ddef.txt,这不是您想要的.
将方括号应用于帐户的编码的唯一方法是使用一个小的解决方法.如果您将完整的URL传递给GetBlobReference方法,SDK会假定您自己完成了所有编码:
var container = account.CreateCloudBlobClient().GetContainerReference("temp");
var blob = container.GetBlobReference(String.Format("{0}/{1}",
container.Uri, System.Web.HttpUtility.UrlEncode("abc[]def.txt")));
blob.UploadFile("myfile.txt");
Run Code Online (Sandbox Code Playgroud)
这会产生正确编码的URL:
http://account.blob.core.windows.net/temp/abc%5b%5ddef.txt
Run Code Online (Sandbox Code Playgroud)
如果你使用像CloudXplorer这样的工具,你会看到具有正确文件名的blob:

| 归档时间: |
|
| 查看次数: |
1435 次 |
| 最近记录: |