ASP.net core MVC catch all route serve static file
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");
}
}
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");
}
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" });
});