有没有办法使所有路线都提供静态文件?
查看此http://blog.nbellocam.me/2016/03/21/Routing-angular-gangular-2-asp-net-core/
我基本上想要这样的东西:
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller}/{action=Index}");
routes.MapRoute("spa", "{*url}"); // This should serve SPA index.html
});
因此,任何与MVC控制器不匹配的路线都将提供wwwroot/index.html
我必须对@davidg答案进行一些补充。这是我最终得到的
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核心捕获Web API和MVC的所有路由的配置不同
使用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();
使用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" });
});
如果您已经处于路由阶段,则已经超越了在管道中提供静态文件的点。您的创业公司看起来像这样:
app.UseStaticFiles();
...
app.UseMvc(...);
这里的顺序很重要。因此,您的应用将首先查找静态文件,从性能的角度来看,这是有意义的 - 如果您只想扔出静态文件,则无需通过MVC管道运行。
您可以创建一个捕获的控制器操作,该操作将返回文件的内容。例如(在评论中窃取代码):
public IActionResult Spa()
{
return File("~/index.html", "text/html");
}
如果您不希望手动指定哪些路由是API:
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc() // suggestion: you can move all the SPA requests to for example /app/<endpoints_for_the_Spa> and let the mvc return 404 in case <endpoints_for_the_Spa> is not recognized by the backend. This way SPA will not receive index.html
// at this point the request did not hit the api nor any of the files
// return index instead of 404 and let the SPA to take care of displaying the "not found" message
app.Use(async (context, next) => {
context.Request.Path = "/index.html";
await next();
});
app.UseStaticFiles(); // this will return index.html
我正在使用的效果很好的是 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
具有相当于您的index.html
。您可能还可以路由到静态页面。
有点删除主题,但是如果您在api
文件夹下的同一项目中也有一个API,则可以为任何与不匹配的API路由设置默认的404响应:
routes.MapRoute(
"apiDefault",
"api/{*url}",
new { controller = "Home", action = "ApiNotFound" });
您最终会以以下行为:
-
/controller
=>没有扩展名,因此请从HomeController.Index
提供SPA默认页面,让Spa处理路由 -
/file.txt
=>检测到的扩展,服务静态文件 -
/api/controller
=>正确的API响应(使用属性路由或为API控制器设置另一个映射) -
/api/non-existent-route
=> 404NotFound()
从HomeController.ApiNotFound
返回
在许多情况下,您需要在一个单独的项目中使用API,但这是可行的替代方案。
为了从wwwroot
文件夹提供index.html
,应添加以下指令(.net Core 2)。
这允许使用静态文件:
app.UseStaticFiles();
这允许获取默认文件,例如index.html
:
app.UseDefaultFiles();
在asp.net core 3.1中,我使用了以下内容:
startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseDefaultFiles();
app.UseStaticFiles();
}
mycontroller.cs
[HttpGet("{anything}")]
public IActionResult GetSPA()
{
return File("~/index.html", "text/html");
}
在.net core 6中,在您的Program.cs
文件中添加app.MapFallbackToFile("index.html");
。
这是带有React项目模板的ASP.NET核心的示例代码:
app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
app.MapFallbackToFile("index.html");
app.Run();