Introduction to ASP.NET Core part 5: static files

Introduction

In the previous post we looked at what middleware means and how it works in .NET Core. A piece of middleware is a component that can be installed during the startup phase of the application in the Configure method of Startup.cs. The components make up a pipeline that the web request travels through until it reaches a so-called terminal component. Once the request has been processed by a terminal component it travels back through the same pipeline in the opposite direct in order to provide some answer to the request. We saw a couple of examples of built-in middleware and we also investigated how to build our own custom component. We also built a wrapper around our component so that it could be easily installed as an extension method of the application builder.

Understanding the basics of middleware is a good foundation for many other areas in .NET as a lot of functionality requires the installation of middleware in Startup.cs. The topic of this post is no exception. We’re going to look at how to work with static files.

We’ll be working in our demo application DotNetCoreBookstore. If you still have the call to…

app.UseEndOfTheWorldComponent();

…in the beginning of the Configure method then don’t forget to either delete it or comment it out otherwise you might not know why the application is not working.

There’s some good documentation of this topic on the relevant Microsoft guide available here.

Static files and the web root

Static files are the files that don’t change dynamically depending on the web request. They are typically JS, image and CSS files or a static welcome page like index.html. By default we put those files in the wwwroot folder in an ASP.NET Core application. Right now it’s empty in our demo app but go ahead and create two subfolders in there: “js” and “css”. Add a javascript file to the js folder called “myscript.js”:

Insert a javascript file in the web root of a .NET Core web application

Let’s just add some javascript code to the file, it doesn’t matter what, we won’t execute it:

function counter() {
    var count = 0;
    return function() {
        return ++count;
    };
}

Next insert a stylesheet to the css folder called mystyle.css:

Insert a css file into a .NET Core application

We add some dummy content into the stylesheet:

body {
   overflow: hidden;
   background: #000000;
}

Next we enter 2 html files directly to the wwwroot folder: index.html and myhome.html.

Here’s the markup of index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Default home page</title>
</head>
<body>
    <p>Welcome to my default index page!</p>
</body>
</html>

…and here’s the markup of myhome.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Customised home page</title>
</head>
<body>
    <p>Welcome to my customised home page!</p>
</body>
</html>

Start the application and extend the localhost URL with /index.html and press Enter. You’ll see that the home page is not found.

Middleware for static files

Handling static files also requires the installation of middleware. Extend project.json with the following package in the dependencies section:

“Microsoft.AspNetCore.StaticFiles”: “1.1.0”

Add the following middleware somewhere before app.Run in the Configure method in Startup.cs:

app.UseStaticFiles();

This enables the serving of static files. Run the application and navigate to /index.html, then /myhome.html, /js/myscript.js and /css/mystyle.css. All of them should work and you should see the requested file content in each case.

UseStaticFiles has an overload where we can specify some options. Let’s say that images are stored in a different folder. Add a folder called Images to the root of the solution. Insert some kind of image in the folder, doesn’t matter what. The good thing is that we can call UseStaticFiles multiple times. Here’s how we can make sure that both the default web root and the configured static folder are also searched:

app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
	FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Images")),
	RequestPath = new PathString("/Img")
});

PhysicalFileProvider is located in the Microsoft.Extensions.FileProviders namespace. Path and Directory are part of the System.IO namespace. We tell the middleware to include the Images folder in the search for static files. RequestPath declares the URL path which corresponds to the physical path. I put an image called “csharpcode.png” in the Images folder, make sure you replace the image name when you try the next example. Run the application and navigate to…:

http://localhost:4427/img/%5Bcsharpcode.png%5D

You should see your image in the browser window.

Default home pages

Normally if we navigate to a web site and don’t provide a specific HTML page, such as http://www.cnn.com, then a default home page is served. The default home page name is usually index.htm(l) or home.htm(l). Right now it doesn’t work in our case. Simply calling the localhost URL leads us to show the JSON output like before. This can be easily remedied with an extra middleware:

app.UseDefaultFiles();

The UseDefaultFiles must come before…:

app.UseStaticFiles();

If you run the application now then the index.html file will be served up. There are 4 default files defined:

  • default.htm
  • default.html
  • index.htm
  • index.html

The first one to be found in wwwroot will be returned. If we now navigate to a non-defined path, like http://localhost:4427/whatever , then we’ll still see the JSON response like before.

We can change this behaviour and declare a different default home page. This is how to set myhome.html as the default home page:

DefaultFilesOptions options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("myhome.html");
app.UseDefaultFiles(options);

Run the application and you should see that myhome.html is served instead of index.html. If that’s not the case then clear your browser cache and rerun the application.

There’s a shortcut to combine UseDefaultFiles and UseStaticFiles called UseFileServer:

app.UseFileServer();

This combines the following two lines of code:

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

It also accepts a couple of options like here to define an additional static file folder:

app.UseFileServer(new FileServerOptions()
{
	FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Images")),
	RequestPath = new PathString("/Img")
});

The built-in welcome page

There’s in fact a “hidden” welcome page that can be activated through a – what else? – piece of middleware. The correct extension method is UseWelcomePage which accepts an optional URL extension as a string:

app.UseWelcomePage("/hello");

Make sure you place this code before the last terminal component which is currently Run.

If you navigate to localhost:port/hello then you’ll see a nice blue screen with a welcome message. This page is a great test page in fact if you want to see whether your ASP.NET Core web application has correctly started on the web server.

We stop here and we’ll continue in the next post.

View the list of MVC and Web API related posts here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

One Response to Introduction to ASP.NET Core part 5: static files

  1. Naveen says:

    nice article..detailed explaination.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: