web-dev-qa-db-fra.com

ASP.net core MVC catch all route serve file static

Existe-t-il un moyen de faire en sorte qu'une route catch all serve un fichier statique?

En regardant cela http://blog.nbellocam.me/2016/03/21/routing-angular-2-asp-net-core/

Je veux essentiellement quelque chose comme ça:

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

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

Donc, toute route qui ne correspond pas à un contrôleur MVC servira wwwroot/index.html

19
Mardoxx

Si vous êtes déjà au stade du routage, vous avez dépassé le point où les fichiers statiques sont servis dans le pipeline. Votre startup ressemblera à ceci:

app.UseStaticFiles();

...

app.UseMvc(...);

L'ordre ici est important. Ainsi, votre application recherchera d'abord les fichiers statiques, ce qui est logique du point de vue des performances - pas besoin de parcourir le pipeline MVC si vous voulez simplement jeter un fichier statique.

Vous pouvez créer une action de contrôleur fourre-tout qui retournera le contenu du fichier à la place. Par exemple (voler le code dans votre commentaire):

public IActionResult Spa()
{
    return File("~/index.html", "text/html");
}
19
DavidG

J'ai dû faire quelques ajouts à la réponse @DavidG. Voici ce que j'ai fini avec

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");
  }
}
32
Ben Anderson

ASP.NET Core intercepte tous les itinéraires pour l'API Web et MVC sont configurés différemment

Avec l'API Web (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();

Avec 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" }); 
});  
18
Ostati

Ce que j'utilise bien, c'est 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 A l'équivalent de votre index.html. Vous pouvez probablement également rediriger vers une page statique.

Un peu hors sujet, mais si vous avez également une API dans le même projet sous un dossier api, vous pouvez définir une réponse 404 par défaut pour toutes les routes d'API qui ne correspondent pas:

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

Vous vous retrouveriez avec le comportement suivant:

  • /controller => Pas d'extension, alors servez la page SPA par défaut de HomeController.Index Et laissez SPA gérer le routage
  • /file.txt => Extension détectée, servir un fichier statique
  • /api/controller => Réponse API appropriée (utilisez le routage d'attributs ou configurez une autre carte pour les contrôleurs API)
  • /api/non-existent-route => 404 NotFound() renvoyé de HomeController.ApiNotFound

Dans de nombreux cas, vous aurez besoin d'une API dans un projet distinct, mais c'est une alternative viable.

3
Nelson Rothermel

Afin de servir index.html du dossier wwwroot les directives suivantes doivent être ajoutées (.Net Core 2).

Cela permet de servir des fichiers statiques:

app.UseStaticFiles();

Cela permet d'obtenir des fichiers par défaut, par ex. index.html:

app.UseDefaultFiles();
1
TSV

Dans le cas où vous ne souhaitez pas spécifier manuellement les itinéraires pour l'api:

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

app.UseMvc()

//return index instead of 404

app.Use(async (context, next) => {
    context.Request.Path = "/index.html";
    await next();
});

app.UseStaticFiles();
0
Daniel