[英]ASP.net core MVC catch all route serve static file
有没有办法让捕获所有路由服务于 static 文件?
看着这个http://blog.nbellocam.me/2016/03/21/routing-angular-2-asp.net-core/
我基本上想要这样的东西:
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller}/{action=Index}");
routes.MapRoute("spa", "{*url}"); // This should serve SPA index.html
});
因此,任何与 MVC controller 不匹配的路由都将提供wwwroot/index.html
我不得不对@DavidG 的回答做一些补充。 这是我最终得到的
启动文件
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller}/{action}");
routes.MapRoute("Spa", "{*url}", defaults: new { controller = "Home", action = "Spa" });
});
家庭控制器.cs
public class HomeController : Controller
{
public IActionResult Spa()
{
return File("~/index.html", "text/html");
}
}
ASP.NET Core 捕获 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 xyz
):
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
=> 404 NotFound()
从HomeController.ApiNotFound
返回在许多情况下,您需要在单独的项目中使用 API,但这是一个可行的替代方案。
为了从wwwroot
文件夹提供index.html
,应添加以下指令(.Net Core 2)。
这允许提供静态文件:
app.UseStaticFiles();
这允许获取默认文件,例如index.html
:
app.UseDefaultFiles();
在 ASP.NET Core 3.1 中,我使用了以下内容:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseDefaultFiles();
app.UseStaticFiles();
}
[HttpGet("{anything}")]
public IActionResult GetSPA()
{
return File("~/index.html", "text/html");
}
在 .NET Core 6 中,添加app.MapFallbackToFile("index.html");
在您的Program.cs
文件中。
以下是来自 ASP.NET Core with React 项目模板的示例代码:
app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
app.MapFallbackToFile("index.html");
app.Run();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.