What is the "right" way to serve new static file extensions?

Hi Everybody, :waving_hand:

I uploaded a *.riv file through the media center and that wasn’t too difficult. I created a media type with a file upload property and set the correct file extension and Umbraco took care of the rest!

But when it came time to serve the file, the server returned a 404.

Now I looked for the “right” way to configure/extend Umbraco to support this file but the only thing I could come up with that worked is below. It seems obtuse to add my own static file handler in front of Umbraco’s. I don’t know what the overhead is, but it’s probably minimal. However, if this is a code smell now, I don’t want to repeat it across other packages that also need to add file extensions.

Is this the “right” way? Is there a “better” way?

Thanks!

using Microsoft.AspNetCore.StaticFiles;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Web.Common.ApplicationBuilder;

public class RiveStaticFileComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.Services.Configure<UmbracoPipelineOptions>(opts =>
        {
            opts.AddFilter(new UmbracoPipelineFilter("Rive", prePipeline: app =>
            {
                var provider = new FileExtensionContentTypeProvider
                {
                    Mappings =
                    {
                        [".riv"] = "application/octet-stream"
                    }
                };

                app.UseStaticFiles(new StaticFileOptions
                {
                    ContentTypeProvider = provider,
                    ServeUnknownFileTypes = false
                });
            }));
        });
    }
}

I think that replaces too much, the cleaner way is something like this:

public class RiveStaticFileComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.Services.Configure<StaticFileOptions>(options =>
        {
            if (options.ContentTypeProvider is FileExtensionContentTypeProvider provider)
            {
                provider.Mappings[".riv"] = "application/octet-stream";
            }
        });
    }
}

Usings:

using Microsoft.AspNetCore.StaticFiles;
using Umbraco.Cms.Core.Composing;

Think that should do the trick.

The default .NET static file middleware knows and handles about 400 different file formats (mime type mappings), but I guess .riv is not one of them.

1 Like

I knew what I was doing had to be over the top!

I’m having a little trouble running the example as-is. With the following change, I was able to serve *.riv files again.

using Microsoft.AspNetCore.StaticFiles;
using Umbraco.Cms.Core.Composing;

public class RiveStaticFileComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        builder.Services.Configure<StaticFileOptions>(options =>
        {
            var provider = options.ContentTypeProvider as FileExtensionContentTypeProvider
                           ?? new FileExtensionContentTypeProvider();
            provider.Mappings[".riv"] = "application/octet-stream";
            options.ContentTypeProvider = provider;
        });
    }
}

(Hopefully I haven’t misunderstood what’s happening under the hood here…)

Thank you @sebastiaan!

1 Like

I’ll admit I didn’t test that code :sweat_smile: so: nice one!

I did find a shorter method, but it would drop any other customizations that other code would’ve made (so if anyone else added mappings then it would drop those and overwrite them with your mappings. So this seems like the best and shortest way to do it.

Should probably be in the docs :light_bulb:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.