ASP.net core MVC catches the entire route, serves a static file

Is there a way to bind the entire route to serve as a static file?

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

Basically I want something like this:

app.UseMvc(routes => { routes.MapRoute("default", "{controller}/{action=Index}"); routes.MapRoute("spa", "{*url}"); // This should serve SPA index.html }); 

Thus, any route that does not match the MVC will serve wwwroot/index.html

+5
source share
5 answers

If you are already at the routing stage, you have passed the point where static files are served in the pipeline. Your launch will look something like this:

 app.UseStaticFiles(); ... app.UseMvc(...); 

The order is important here. Thus, your application will first look for static files, which makes sense in terms of performance - there is no need to run through the MVC pipeline if you just want to throw away the static file.

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

 public IActionResult Spa() { return File("~/index.html", "text/html"); } 
+8
source

I had to make some additions to @DavidG's 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"); } } 
+17
source

ASP.NET Core catches all routes for web API and MVC, configured differently

With the 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.UseDefaultFiles(); app.UseStaticFiles(); app.UseMvc(); 

With MVC ( dotnet add package Microsoft.AspNetCore.SpaServices -Version xyz ):

 app.UseDefaultFiles(); app.UseStaticFiles(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}"); routes.MapSpaFallbackRoute("spa", new { controller = "Home", action = "Index" }); }); 
+8
source

What I use works well Microsoft.AspNetCore.Builder.SpaRouteExtensions.MapSpaFallbackRoute :

 app.UseMvc(routes => { // Default route for SPA components, excluding paths which appear to be static files (have an extension) routes.MapSpaFallbackRoute( "spaFallback", new { controller = "Home", action = "Index" }); }); 

HomeController.Index has the equivalent of your index.html . Perhaps you can also go to a static page.

Disable the theme, but if you also have an API in the same project in the api folder, you can set the default 404 response for any API routes that do not match:

 routes.MapRoute( "apiDefault", "api/{*url}", new { controller = "Home", action = "ApiNotFound" }); 

As a result, you get the following behavior:

  • /controller => There is no extension, so open the default SPA page from HomeController.Index and let SPA handle routing
  • /file.txt => Detected extension, serves for a static file
  • /api/controller => correct API response (use attributive routing or configure another map for API controllers)
  • /api/non-existent-route => 404 NotFound() returns from HomeController.ApiNotFound

In many cases, you will need the API in a separate project, but this is a viable alternative.

+1
source

To serve the index.html folder from wwwroot , the following directives (.Net Core 2) should be added.

This allows you to serve static files:

 app.UseStaticFiles(); 

This allows you to get default files, for example. index.html :

 app.UseDefaultFiles(); 
0
source

Source: https://habr.com/ru/post/1264620/


All Articles