I’m moving a ClickOnce install from a regular web server to Azure Blob storage and have a problem with some of the files. The filenames contains [ ] and CloudBlob.UploadFile fails with an exception:
Microsoft.WindowsAzure.Storageclient.StorageException:
Error accessing blob storage: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
The code has been used for a while and only fails on files with [ ] in the name so I don’t believe that it is an “authentication failure”. In this particular case, this is the seventh file being uploaded in a loop. I found this link on MSDN about valid file names and this on stack overflow which both show problems with square brackets in URL’s and reference UrlEncode. I added in a call to UrlEncode and that did not help. The container is created with public access since we use it to support customer downloads of our software. We have been hosting a “test” install in another container and have not had permission problems accessing that either.
I can upload the file with no name changes and then rename the file to add the “path” using newdesic’s Azure Storage Explorer tool so what is that doing that I am not doing?
I see you’re using the 1.7 SDK. This is a small encoding issue with the SDK which is also present in v2.0. Let’s see what happens.
No encoding
If you don’t encode the blob name, you’ll end up with a request to the following URL which is causing the authentication exception:
The is because the SDK uses
Uri.EscapeUriStringinternally to encode your string, but this doesn’t take into account square brackets.Encoding
Then you would expect the following to do the trick:
The issue here is that you’ll end up with this url:
So what’s happening here? Calling HttpUtility.UrlEncode turns abc[]def.txt to abc%5B%5Ddef.txt, which is correct. But internally, the SDK will encode this string again which results in abc%255b%255ddef.txt, which isn’t what you want.
Workaround
The only way to apply encoding which takes square brackets into accounts is by using a small workaround. If you pass the full URL to the GetBlobReference method, the SDK assumes you did all the encoding yourself:
This results in a correctly encoded URL:
And if you use a tool like CloudXplorer, you’ll see the blob with the correct filename: