Correct MIME Type Not Always Being Returned In ASP.NET On Azure
I recently faced an issue where the MIME type for a .mp4
file was being returned from an Azure Web App as application/octet-stream
and not the video/mp4
I was seeing locally.
Code
var filename = "test.mp4";
var mimeType = MimeMapping.GetMimeMapping(filename);
Output
Locally: video/mp4
In Azure: application/octet-stream
What’s going on?!
After some head scratching as to how a static class with a static method could return different results given the same inputs, I decided to dig into the source code.
MimeMapping.cs in the GitHub repo for the Microsoft .NET Reference SourceIn the file MimeMapping.cs
, you can see mappings of file extension to MIME type but there’s no mapping for .mp4
files.
// MimeMapping.cs around line 246
AddMapping(".mp2", "video/mpeg");
AddMapping(".mp3", "audio/mpeg");
AddMapping(".mpa", "video/mpeg");
AddMapping(".mpe", "video/mpeg");
How was video/mp4
being returned locally for an .mp4
file extension then? The answer lies further down in the code in the file MimeMapping.cs
.
// MimeMapping.cs around line 448
// This can provide mappings from the actual applicationHost.config file in IIS7 integrated mode
private sealed class MimeMappingDictionaryIntegrated : MimeMappingDictionaryBase {
private readonly IntPtr _applicationContext;
public MimeMappingDictionaryIntegrated(IntPtr applicationContext) {
_applicationContext = applicationContext;
}
protected override void PopulateMappings() {
IntPtr mimeMapCollection = IntPtr.Zero;
try {
int result;
int mimeMapCount;
// Read the collection
result = UnsafeIISMethods.MgdGetMimeMapCollection(IntPtr.Zero, _applicationContext, out mimeMapCollection, out mimeMapCount);
...
The class MimeMappingDictionaryIntegrated
can provide mappings based on IIS configuration.
If MimeMapping
is hosted within an ASP.NET application, the internal method SetIntegratedApplicationContext
is called and additional MIME type mappings from the IIS configuration are available.
On my local machine, the IIS Express root configuration file applicationhost.config
in the folder C:\Program Files (x86)\IIS Express
(location can vary) contains the following:
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
Bingo! That explains why locally the .mp4
extension is mapped to video/mp4
.
It appears the default Azure Web App configuration does not include this mapping and therefore the default MIME type of application/octet-stream
is returned instead.
Let’s have a look at a couple of solutions to resolve this issue of missing MIME type mappings.
Solution 1 — Add a MIME mapping in web.config
The first solution is to add the MIME type mapping for the extension .mp4
to your project’s web.config
.
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".mp4" />
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
</staticContent>
</system.webServer>
</configuration>
Solution 2 — Use a different MIME type mappings source
The
GitHub project MimeTypeMap
provides a much more extensive mapping of file extensions to MIME types (which includes .mp4
).
The code is packaged up and available via the
NuGet package MimeTypeMap.List
.