簡體   English   中英

ASP.net 核心 MVC 捕獲所有路由服務 static 文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM