在 Dotnet 8 以前,微軟有提供過 WASM 可以直接給 API server 託管的功能,等於是只要架一個網站就可以前後端分離,但這樣的設定會衍生打不存在的 API 不會回傳 404,反而是回傳前端 index.html。
託管設定
想要託管在 API Server,先從 nuget 安裝 Microsoft.AspNetCore.Components.WebAssembly.Server
,並且在 Program.cs
加上兩行,再把前端的專案加入參考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseBlazorFrameworkFiles(); app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.MapFallbackToFile("index.html");
app.Run();
|
改完以後,就可以用 server 跑起來,在同一個網站有前後端。
這時候可以測試一個 GET api/test
,正常預期是 404,但實際上是回傳 index.html
的內容。
調整
這個問題主要是因為 MapFallbackToFile
沒有區分前後端,因此要分開這兩個行為,可以透過 MapWhen
來做判斷。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| app.MapWhen(ctx => !ctx.Request.Path.StartsWithSegments("/api"), blazor => { blazor.UseBlazorFrameworkFiles(); blazor.UseStaticFiles(); blazor.UseRouting();
blazor.UseEndpoints(endpoints => endpoints.MapFallbackToFile("index.html")); });
app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/api"), api => { api.UseStaticFiles(); api.UseRouting(); api.UseAuthentication();
api.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllers(); }); });
|
其中 UseRouting
必須要在兩邊都寫不能寫在外面,不然可能不會回 404。
這樣改完以後,再次嘗試 api/test
就可以得到 404。
Reference
c# - How to map fallback in ASP .NET Core Web API so that Blazor WASM app only intercepts requests that are not to the API - Stack Overflow