Solving the MIME issue with Azure Blob Storage

By default anything you upload to blob storage will have the MIME type or content type of
application/octet-stream

You must specify the type before you upload the blob. This post covers solving the issue of your current blobs and a solution for uploading from your application.

My post deals with solving the issue during deployment with a PowerShell script in VSTS.

The Problem

The build files for an Angular app are copied to blob storage which is integrated with Azure CDN. Incorrect MIME types were causing issues in the browser.

The Solution

Since these files are created during deployment the best solution was to run a PowerShell script task during the build process. The script would correct the MIME type for every file in the container.

The How

Windows Azure PowerShell module

Follow these instructions to install the Windows Azure PowerShell module on your build agent.


Microsoft.WindowsAzure.Storage.dll

To get the dll file, download the WindowsAzure.Storage nuget package. Nupkg files are just zip files. After extracting the file, copy the dll from the folder path WindowsAzure.Storage.9.1.0\lib\net45
I just copied the dll to the root of the drive, so the path to the file is
C:\Microsoft.WindowsAzure.Storage.dll


VSTS Task

I'm using the version 2 preview of the PowerShell utility task in my build definition on VSTS. It is the the last task to run.


PowerShell Script
try
{
$ContainerName = "Your Container Name" 
$StorageAccountName="Your Storage Account Name"

If((Get-Module -ListAvailable Azure) -eq $null){
Write-Warning "Windows Azure PowerShell module not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools"
}
Else
{
Function ChangeBlobContentType
{
Param ([String]$ContainerName)
Write-Verbose "Getting the container object named $ContainerName."
$BlobContainer = $CloudBlobClient.GetContainerReference($ContainerName)
Write-Verbose "Getting the blob object named $BlobName."
$Blobs = $BlobContainer.ListBlobs("","true")

foreach ($file in $Blobs) {
$file
$extension = [System.IO.Path]::GetExtension($file.Name)

if($extension -Match ".js"){
$file.Properties.ContentType = "application/javascript"
$file.SetProperties()
}

if($extension -Match ".png"){
$file.Properties.ContentType = "image/png"
$file.SetProperties()
}

if($extension -Match ".svg"){
$file.Properties.ContentType = "image/svg+xml"
$file.SetProperties()
}

if($extension -Match ".jpg"){
$file.Properties.ContentType = "image/jpeg"
$file.SetProperties()
}

if($extension -Match ".jpeg"){
$file.Properties.ContentType = "image/jpeg"
$file.SetProperties()
}

if($extension -Match ".gif"){
$file.Properties.ContentType = "image/gif"
$file.SetProperties()
}

if($extension -Match ".ico"){
$file.Properties.ContentType = "image/x-icon"
$file.SetProperties()
}

if($extension -Match ".eot"){
$file.Properties.ContentType = "application/vnd.ms-fontobject"
$file.SetProperties()
}

if($extension -Match ".otf"){
$file.Properties.ContentType = "application/font-sfnt"
$file.SetProperties()
}

if($extension -Match ".ttf"){
$file.Properties.ContentType = "application/font-sfnt"
$file.SetProperties()
}

if($extension -Match ".woff"){
$file.Properties.ContentType = "application/font-woff"
$file.SetProperties()
}

if($extension -Match ".woff2"){
$file.Properties.ContentType = "font/woff2"
$file.SetProperties()
}     

$file.Properties.ContentType
}
}

If($StorageAccountName){
#Specify a Windows Azure Storage Library path
$StorageLibraryPath = "C:\Microsoft.WindowsAzure.Storage.dll"
$StorageAccountKey = "Your Storage Account Key"

Write-Verbose -Message "Loading Windows Azure Storage Library from $StorageLibraryPath" [Reflection.Assembly]::LoadFile("$StorageLibraryPath") | Out-Null

$Creds = New-Object Microsoft.WindowsAzure.Storage.Auth.StorageCredentials("$StorageAccountName","$StorageAccountKey")
$CloudStorageAccount = New-Object Microsoft.WindowsAzure.Storage.CloudStorageAccount($creds, $true)
$CloudBlobClient = $CloudStorageAccount.CreateCloudBlobClient()
}

If($ContainerName){
ChangeBlobContentType -ContainerName $ContainerName
}
}
}
catch{
Write-Error $_.Exception.ToString()
Read-Host -Prompt "The above error occurred. Press Enter to exit."
}

Putting It Together

VSTS Angular Build Definition Above is the build definition for the Angular app.
The PowerShell script dealt with a few MIME types, if you need all your bases covered then check out this GitHub project.