Search code examples
c#asp.net-core.net-corestatic-files

Asp.Net Core StaticFiles include / exclude rules


I've setup static files and directory browsing like this:

    PhysicalFileProvider physicalFileProvider = new PhysicalFileProvider(somePath, ExclusionFilters.None);
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = physicalFileProvider,
        RequestPath = "/files",
        ServeUnknownFileTypes = true
    }); 

    app.UseDirectoryBrowser(new DirectoryBrowserOptions
    {
        FileProvider = new PhysicalFileProvider(somePath),
        RequestPath = "/files"
    });

I've been searching documentation and browsing through object models but I can't figure out how to set the include and exclude filters. My current code is filtering files starting with . (hidden? but I'm running on Windows ) I want to show and download these files but hide other types such as *.json and web.config.


Solution

  • This is a bit of a hack, but it worked for me. You can make a new fileprovider that uses PhysicalFileProvider (or anything else really) under the hood, but hides files according to a pattern.

    public class TplFileProvider : IFileProvider
    {
        private readonly IFileProvider fileProvider;
    
        public TplFileProvider(string root)
        {
            fileProvider = new PhysicalFileProvider(root);
        }
        public TplFileProvider(string root, ExclusionFilters exclusionFilter)
        {
            fileProvider = new PhysicalFileProvider(root, exclusionFilter);
        }
    
        public IDirectoryContents GetDirectoryContents(string subpath)
        {
            return (IDirectoryContents) fileProvider.GetDirectoryContents(subpath).Where(i => isAllowed(i.Name));
        }
    
        public IFileInfo GetFileInfo(string subpath)
        {
            var file = fileProvider.GetFileInfo(subpath);
            if (isAllowed(subpath))
            {
                return file;
            }
            else
            {
                return new NotFoundFileInfo(file.Name);
            }
        }
    
        private static bool isAllowed(string subpath)
        {
            return subpath.EndsWith(".json") || subpath.Equals("web.config");
        }
    }
    

    Edit: Here's a better way to do it using filetype whitelist:

    var path = Path.GetFullPath(rawPath);
    
    var mapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
        {
            { ".json", "application/json" },
            { ".jpg", "image/jpeg" },
            { ".png", "image/png" },
        };
    staticFileOptions = new StaticFileOptions()
    {
        RequestPath = "/StaticTiles",
        ServeUnknownFileTypes = false,
        ContentTypeProvider = new FileExtensionContentTypeProvider(mapping),
        FileProvider = new PhysicalFileProvider(path),
    };
    app.UseStaticFiles(staticFileOptions);