ASP.NET Core MVC捕获所有路由服务静态文件



有没有办法使所有路线都提供静态文件?

查看此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 => 404 NotFound()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();

最新更新