When using Shared Access Signature (SAS) with Windows Azure, it is best to use Uri.AbsoluteUri() instead of Uri.ToString()

Recently I experienced an issue in which the following code was not able to generate a URI that is suitable for use as a URL in web transactions. You might have seen no problem at all using Uri.ToString() however the same code sometimes failed to generate an URL which can be used properly:

  var storageCredentialsAccountAndKey = new StorageCredentialsAccountAndKey(
 "your_storage_name",
 "your_storage_key");
 
 var cloudBlobClient = new CloudBlobClient(
 "https://your_storage_url", 
 storageCredentialsAccountAndKey);
 
 var uri = "https://your_storage_url/container_name/blob_name.extension";
 var cloudBlob = cloudBlobClient.GetBlobReference(uri);
 var sas = cloudBlob.GetSharedAccessSignature(
 new SharedAccessPolicy
 {
 Permissions = SharedAccessPermissions.Read,
 SharedAccessStartTime = DateTime.Parse("Date_Time_Value"),
 SharedAccessExpiryTime = DateTime.Parse("Date_Time_Value"),
 });
 
 Console.WriteLine(sas);
 var uriValue = new Uri(uri + sas);
 Console.WriteLine(uriValue.ToString());
 

What I found is that same CloudBlob.GetSharedAccessSignature() function was not able to encode the signature part of the string correctly if the signature has '+' in it. The same code does work fine sometime.

 

Conclusion:

Uri.AbsoluteUri() is almost always a better choice. Uri.ToString() produces something like a human-readable version of the URI. So if you are using Uri.AbsoluteUri that is the best decision to use and the best choice.

GetSharedAccessSignature() returns you a string so when you have “+” sign in your url, probably the right thing to do with it is to combine it with something and new Uri() it. The new Uri() would encode the string correctly.