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
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");
}
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");
}
}
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" });
});
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.
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();
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();