The built-in Azure Storage account in Sitefinity is great - it allows you to upload media items (images, files, videos) directly to Azure Storage account, which has many benefits like unlimited storage at a low cost, redundancy, etc.
Below are some of the gotchas I found while working with it in version 9.2:
1. Exception like this during upload:Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (403) Forbidden
....StatusMessage:Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature
If you go to Administration > Settings > Storage Providers and click on your Azure storage provider and then Test Settings - you will see the above 403 Forbidden message as well.Reason and Solution
: in my case it was the time on the server where the site is hosted was wrong (e.g. Timezone was set to Sydney, but time was showing UTC time, go figure).
Azure does not allow you to upload files to the storage account if there is more than 15 min difference between the time header that the server sends and the real time. So, Azure denies the request in this case.
2. Cannot download a video file hosted on Azure Storage
The reason for this is a missing Content-Disposition
response header. Even if you manually set this header via Azure Storage Explorer
or an API, you will see that the response still does not include the header and the video is played inline instead of being downloaded. The reason for this is that the Content-Disposition
header works with Azure services version (x-ms-version)
2013-08-15 or later. Unfortunately, Sitefinity provider does not set the version during the initialization, so a very old x-ms-version is used by default: x-ms-version: 2009-09-19
Figure: default x-ms-version response header is quite outdated
As a result, no Content-Disposition header is included in the response.
We can read from here
"If a request to the Blob service does not specify the
x-ms-version header, and the default version for the service has not been set using Set Blob Service Properties, then the earliest version of the Blob service is used to process the request. However, if the container was made public with a Set Container ACL operation performed using version 2009-09-19 or newer, then the request is processed using version 2009-09-19.
So, if you have a video hosted on Azure and you want to allow your users to be able to download it, there is no way to make it work across all browsers, due to old Azure Service version never including the content-disposition response header.Solution
: First set the x-ms-version
of the Azure Service to a newer version via the API - this is done only once, and from then on all Azure responses include the new version as below:
Here is a sample code that updates the x-ms-version header:
Now that we have the newer x-ms-version, we can set the Content-Disposition header to a video file of our choice in Azure Storage Explorer like this:
Now if you request that video file - it will start downloading automatically.
3. Regenerate Thumbnails task fail for a library hosted on Azure Cloud Storage
The error message that is shown in the backend UI is this:
"Unable to update some MediaContent. Check trace log for details
The trace.log file has the following exception:
Message: Unable to update MediaContent item 'ImageLargerThan4MB' with ID=5ce0ae09-7566-6239-863f-ff00003d40d7: System.ArgumentException: Parameter is not valid.
at DynamicModule.ns.Wrapped_OpenAccessLibrariesProvider_ca21ba6d06bb4f83810633549740053b.RegenerateThumbnails(MediaContent mediaContent, String profilesFilter)
at Telerik.Sitefinity.Modules.Libraries.LibraryThumbnailsRegenerateTask.UpdateItem(LibrariesManager manager, MediaContent content)
This happens for images that are larger than 4MB - in order to regenerate the thumbnails of the image, Sitefinity first downloads the original image, but there is a bug in the Azure SDK version that Sitefinity uses as shown in this SO thread
"I have observed that when file is uploaded using blob.UploadText() method, it works fine but when blob is uploaded using OpenWrite method as done in following code sample, the OpenRead Method reads only 4194304 bytes (4 mb).
"This was probably a bug in Microsoft.WindowsAzure.StorageClient.dll (assembly version 6.0.6002.17043) that comes with SDK v1.2. It works with latest Microsoft.WindowsAzure.StorageClient.dll (assembly version 6.0.6002.18312 - SDK v1.4).
What can you do - if the number of images that are larger than 4MB is not big - you can try resizing them first and re-uploading them again.
Alternatively, you can try moving the library to a Database storage first (which seems to download the files ok), regenerate thumbnails and then move it back to Azure storage.