Static Files in ASP.NET Core

An ASP.NET Core Web Application is very strict about only serving resources from its Web Root, which is normally <website-root>/wwwroot. This is to prevent files that could help attackers compromise your site from being served. When you build, you use a tool like Gulp, any other, or just copy and paste, to move all files that must be served into wwwroot. Just to keep things even tighter, by default, no static files will be served from this folder.

To allow your app to serve static files from its Web Root, you must install the Microsoft.AspNetCore.StaticFiles package. You can do this using NuGet, or in the nice new way that .NET Core allows: just add the line "Microsoft.AspNetCore.StaticFiles": "1.0.0" to the dependencies object in your project.json file. As soon as you save that file, Visual Studio will automatically download and install the package. Some more magic: if you don’t just copy and paste that line into project.json, after you type the package name and colon, when you type the opening double-quote for the version, the editor will give you Intellisense for which versions are available. Normally you would just choose the latest.

After adding the StaticFiles package, you need to add the following two lines to the Configure method of your project’s Startup.cs class:

app.UseDefaultFiles();
app.UseStaticFiles();

The first line means that Kestrel will look for default files, like default.html and index.html, in the Web Root folder, and automatically serve them if no other page is requested in the URL. For some mysterious reason, this line must always be placed before the static files line.

You can change which directory static files may be served from, but, for what I think was a very bad design decision, the application can always serve static files from one directory only. Maybe one day we’ll find out why.

Now if you have used any npm packages in your project, they are installed into a folder called node_modules. After adding just a few modules, this folder can become full. On a simple little Hello world type project with Angular 2, my node_modules folder contains 16,847 files, and takes up 107MB of disk space. Node.js, what is your story, coming in and making tiny, thin .NET projects obese?

The problem with npm is that all the JavaScript files that you must add to your web pages reside somewhere in node_modules, and they won’t be served, because the app is only serving static files from wwwroot. To remedy this, I had ended up with my Configure method looking like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseFileServer();
    var provider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "node_modules"));
    var options = new FileServerOptions();
    options.RequestPath = "/node_modules";
    options.StaticFileOptions.FileProvider = provider;
    options.EnableDirectoryBrowsing = true;
    app.UseFileServer(options);
 
    loggerFactory.AddConsole();
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
}

I have since found out that UseFileServer() incorporates the functionality in those two lines in my first code block, so I am investigating removing them and only using UseFileServer(), but for now my app works as is, and I will only update this post after some thorough testing.

The Promised ReadMe File for the Angular 2 Tutorial Project

In yesterday’s post I described a little project where I had integrated the Angular 2 QuickStart tutorial from Angular, into an ASP.NET Core web application. I also promised to add a missing readme file to the project to help developers understand how I “merged” the two.

This is cutting edge stuff, but the first step is very simple and aimed at beginners. Yet with new tech, we are all always a beginner at something.

So, the code is on GitHub, over here: https://github.com/erisiasoft/Angular2Tutorials