Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.net core MVC catch all route serve static file

Is there a way to make a catch all route serve a static file?

Looking at this http://blog.nbellocam.me/2016/03/21/routing-angular-2-asp-net-core/

I basically want something like this:

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

            routes.MapRoute("spa", "{*url}"); // This should serve SPA index.html
        });

So any route that doesn't match an MVC controller will serve up wwwroot/index.html

like image 522
Mardoxx Avatar asked Feb 23 '17 11:02

Mardoxx


3 Answers

I had to make some additions to @DavidG answer. Here is what I ended up with

Startup.cs

app.UseStaticFiles();

app.UseMvc(routes =>
{
   routes.MapRoute("default", "{controller}/{action}");

   routes.MapRoute("Spa", "{*url}", defaults: new { controller = "Home", action = "Spa" });
});

HomeController.cs

public class HomeController : Controller
{
  public IActionResult Spa()
  {
      return File("~/index.html", "text/html");
  }
}
like image 94
Ben Anderson Avatar answered Nov 17 '22 18:11

Ben Anderson


ASP.NET Core catch all routes for Web API and MVC are configured differently

With Web API (if you're using prefix "api" for all server-side controllers eg. Route("api/[controller"]):

app.Use(async (context, next) => 
{ 
    await next(); 
    var path = context.Request.Path.Value;

    if (!path.StartsWith("/api") && !Path.HasExtension(path)) 
    { 
        context.Request.Path = "/index.html"; 
        await next(); 
    } 
});            

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

app.UseMvc();

With MVC (dotnet add package Microsoft.AspNetCore.SpaServices -Version x.y.z):

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

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

    routes.MapSpaFallbackRoute("spa", new { controller = "Home", action = "Index" }); 
});  
like image 29
Ostati Avatar answered Nov 17 '22 18:11

Ostati


If you're already in the routing stage, you've gone past the point where static files are served in the pipeline. Your startup will look something like this:

app.UseStaticFiles();

...

app.UseMvc(...);

The order here is important. So your app will look for static files first, which makes sense from a performance standpoint - no need to run through MVC pipeline if you just want to throw out a static file.

You can create a catch-all controller action that will return the content of the file instead. For example (stealing the code in your comment):

public IActionResult Spa()
{
    return File("~/index.html", "text/html");
}
like image 25
DavidG Avatar answered Nov 17 '22 19:11

DavidG