54

How can I get asp.net core to serve an index.html file from inside my wwwroot?

The reason I want to do this is because I an developing an angular 4 app using the angular CLI and it takes care of the entire build process. I have set it up to build into the wwwroot directory of my asp.net core project but asp.net core doesn't want to serve it.

At first I tried to return the html file through a controller. I tried this route:

app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}");
    });

And then in the controller I return the html file like this:

public IActionResult Index()
{
    var webRoot = _env.WebRootPath;
    var path = System.IO.Path.Combine(webRoot, "index.html");

    return File(path, "text/html");
}

This didn't work. It returned a 404 not found exception and gave the path but the path it gave was the correct path to the index.html file (I cut and pasted it into explorer and the file opened).

I am also declaring these in startup:

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

I then tried removing the default route. Now I am able to get to the index.html file but only if I type the filename in, i.e.:

localhost:58420/index.html

If I try to access the root of the domain without the "index.html" specified I get a 404 error.

What is the proper way to reference the index.html as the default page? I am guessing doing it from a controller is probably better because then it will be compatible with angular routing without rewrites.

Guerrilla
  • 13,375
  • 31
  • 109
  • 210
  • is your controller name `HomeController`? – Set Mar 29 '17 at 10:30
  • Yes, the acton I pasted above was firing and with the correct file path but it gives a 404 file not found exception and specifies the correct path in the exception. Maybe some security issue serving from inside the wwwroot folder? – Guerrilla Mar 29 '17 at 10:31
  • `(I cut and pasted it into explorer and the file opened).` Yes, path is defienitely correct – Guerrilla Mar 29 '17 at 10:53

8 Answers8

88

Just use this in startup.cs:

app.UseFileServer();

It's shorthand for:

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

it avoids issues with having to have those in the correct order (as shown above)

rfcdejong
  • 2,219
  • 1
  • 25
  • 51
Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206
  • 3
    Marking this as answer because better solution – Guerrilla Jun 27 '18 at 22:16
  • 1
    If you have trouble getting this to work on a new project, make sure you didn't leave the default `app.Run(async (context) => await context.Response.WriteAsync("Hello World!"));` at the end of your `Configure` method. That'll intercept the request when you browse to your site root, preventing you from going to the default page. – Ryan Lundy Jan 16 '19 at 15:24
  • 4
    The word **order** should be highlighted...it killed me at least 30 mins :( – David S. Jun 19 '19 at 05:26
41

I needed to declare UseDefaultFiles() before UseStaticFiles().

app.UseDefaultFiles();
app.UseStaticFiles();
Guerrilla
  • 13,375
  • 31
  • 109
  • 210
  • 7
    Whoever designed junk to misbehave because of the order like this should be shot, hung and then shot again. Twice. Took me an hour of fighting because I though I missed something in the general setup or access rights... Why do they even collide?! The one let's e.g. JS files to be served while the other completes a path with e.g. *index.html*. WTF?! – Konrad Viltersten Dec 31 '18 at 14:48
  • 4
    @KonradViltersten it's a pipeline... that whole section goes in order. That way you can control what happens when. i.e. Authentication first, then MVC, etc... – kjbetz May 05 '19 at 15:40
15

Feb 2022 Update

To serve static files (such as index.html), the files should be in the folder wwwroot in your project. Use UseWebRoot if you want to change it to a different folder.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseFileServer();
}

This method also accepts a FileServerOptions instance for even more fine tuned control such as enabling directory browsing, which is disabled by default.

Reference: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files

Original answer (Jan '18)

Install the NuGet package Microsoft.AspNetCore.StaticFiles.

Now, in Startup.Configure method, add:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Serve the files Default.htm, default.html, Index.htm, Index.html
    // by default (in that order), i.e., without having to explicitly qualify the URL.
    // For example, if your endpoint is http://localhost:3012/ and wwwroot directory
    // has Index.html, then Index.html will be served when someone hits
    // http://localhost:3012/
    //
    // (Function 1)
    app.UseDefaultFiles();

    // Enable static files to be served. This would allow html, images, etc. in wwwroot
    // directory to be served.
    //
    // (Function 2)
    app.UseStaticFiles();
}

Note: The order in which these functions are called is important. In OO programming, it's quite hard not to depend on ordering as objects maintain states that can vary during the lifetime of the object. (You guessed it right, one solution to prevent designs like these is to implement immutability.)

You should now get files served from wwwroot directory (use UseWebRoot if you want to change it to something else).

Source: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files

Sachin Joseph
  • 18,928
  • 4
  • 42
  • 62
8
app.UseDefaultFiles(new DefaultFilesOptions {
    DefaultFileNames = new List<string> { "index.html" }
});
app.UseStaticFiles();

This is optimal since the UseDefaultFiles URL rewriter will only search for index.html, and not for the legacy files: default.htm, default.html, and index.htm.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-2.2#serve-a-default-document

KTCO
  • 2,115
  • 23
  • 21
  • Did you mean it is *"optional"* - as it "you don't have to do it, because the URL rewriter will already search for `index.html` for you? – Ian Boyd Jun 06 '23 at 12:58
1

In the startup.cs inside the configureservices method apply this. Here we create a DefaultFilesOption object and then clear all the defaultfiles set in the path. Next, we add the path of the file we want to set as default. And then we inject the dependency using ' app.UseDefaultFiles(defaultfileoptions). Also, we need to inject static files as dependencies.

`

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){
    DefaultFilesOption defaultFileOptions = new DefaultFilesOption();
    defaultFileOptions.DefaultFileNames.Clear();
    defaultFilesOptions.DefaultFileNames.Add("Index.html");
    app.UseDefaultFiles(defaultFileOptions);
    app.UseStaticFiles();
}  

`

0

// By default ASP.net core does not serve the static files such as HTML, css, image etc... I need to configure the middleware in the request processing pipeline for serving static files.

// This code would be written in Startup.cs class for configuring the middleware components.



  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {

        app.UseDefaultFiles(); // This sets the default page redirection for the in-comming request
            app.UseStaticFiles(); // This serves the static files to the client.

        }
Sheo Dayal Singh
  • 1,591
  • 19
  • 11
-2

You are mixing both MVC and Default files serving (useDefaultFiles). Comment out the below lines from your code

app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}");
    });

and use only app.UseDefaultFiles();. It will start working.

boop_the_snoot
  • 3,209
  • 4
  • 33
  • 44
satty
  • 1
-8
return File(System.IO.File.OpenRead(Path.Combine(HostingEnvironment.WebRootPath + "/index.html")), "text/html");

It has to help u

Evan Bor
  • 29
  • 1
  • 5