Can I have different MIME type mappings for different files with the same extension (in the same folder)?

Viewed 116

Introduction

I'm configuring MIMEs for static files as usual, something like this (and that works fine, keep reading so you get to the actual question):

var defaultStaticFileProvider = new PhysicalFileProvider(Path.Combine(webHostEnvironment.ContentRootPath, "content"));
var contentTypeProvider = new FileExtensionContentTypeProvider();            
var defaultStaticFilesRequestPath = "/content";
// This serves static files from the 'content' directory.
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = defaultStaticFileProvider,
    ServeUnknownFileTypes = false,
    RequestPath = defaultStaticFilesRequestPath,
    ContentTypeProvider = contentTypeProvider
});

The previous code is mapping the .json extension to application/json by default. Works fine.

Question

What I want is to change that mapping to application/manifest+json but only for one file: manifest.json

So, I tried to add another configuration like this (not working):

// Add custom options for manifest.json only.
var manifestContentTypeProvider = new FileExtensionContentTypeProvider();
manifestContentTypeProvider.Mappings.Clear();
manifestContentTypeProvider.Mappings.Add(".json", "application/manifest+json");
var manifestStaticFileProvider = new PhysicalFileProvider(Path.Combine(webHostEnvironment.ContentRootPath, "content/en/app"));
var manifestStaticFileRequestPath = "/content/en/app/manifest.json";
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = manifestStaticFileProvider,
    ServeUnknownFileTypes = false,
    RequestPath = manifestStaticFileRequestPath,
    ContentTypeProvider = manifestContentTypeProvider
});

Just to clarify, I have added the above code right after the previous one.

Hope the question is clear enough, I'll be checking for comments proposing editing tips to make it better anyways.

1 Answers

The StaticFileOptions class has an OnPrepareResponse property to which you can assign an Action in order to change the HTTP response headers.

From the documentation

Called after the status code and headers have been set, but before the body has been written. This can be used to add or change the response headers.

In that Action you check for the manifest.json file and set/change the content-type header accordingly. That action has an StaticFileResponseContext input argument with access to the HttpContext and File.

var options = new StaticFileOptions
{
    OnPrepareResponse = staticFileResponseContext =>
    {
        var httpContext = staticFileResponseContext.Context;

        // Request path check:
        if (httpContext.Request.Path.Equals("/content/en/app/manifest.json", StringComparison.OrdinalIgnoreCase))
        // or file name only check via: 
        // if (staticFileResponseContext.File.Name.Equals("manifest.json", StringComparison.OrdinalIgnoreCase))
        {
            httpContext.Response.ContentType = "application/manifest+json"
        }
    },
    // Your other custom configuration
    FileProvider = defaultStaticFileProvider,
    ServeUnknownFileTypes = false,
    RequestPath = defaultStaticFilesRequestPath
};

app.UseStaticFiles(options);
Related