Blazor WASM 路由 Post 请求到 index.html

Blazor WASM Route Post Request to index.html

我使用 Visual Studio 模板设置了一个 Blazor WASM 应用程序。我在服务器项目的 Startup.cs 文件中的路由如下所示:

app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllers();
    endpoints.MapFallbackToFile("index.html",);
});

这一直工作得很好,每当我向没有控制器的路由发出 GET 请求时,都会从我的客户端项目中提供 wwwroot/index.html 文件。 Client 项目中的 Blazor 框架将它用于那里。但是,我现在需要支持从 GET 或 POST 请求向我的应用程序中没有控制器的端点发送 returning index.html 文件。我真的很难弄清楚如何设置它。我已经尝试了 EndpointRouteBuilderExtensions.MapPost 方法并且能够 return 字符串但是没有看到任何将它用于 return 文件的好例子。这不起作用:

endpoints.MapPost("*", (HttpContext context) => {
    context.Request.Path = "/index.html";
    context.SetEndpoint(null);
});

尽管它类似于框架方法StaticFilesEndpointRouteBuilderExtensions.MapFallbackToFile所做的:https://github.com/dotnet/aspnetcore/blob/fc4e391aa58a9fa67fdc3a96da6cfcadd0648b17/src/Middleware/StaticFiles/src/StaticFilesEndpointRouteBuilderExtensions.cs#L194

我的问题与这个问题类似: 但那里的答案不适合我的情况。

我有一种方法可以帮助你。您可以告诉网络服务器路由它找不到给您的任何路由 index.html。 Nginx 中的语法是

try_files $uri $uri/ /index.html =404;

不确定这是否会解决您的问题,因为我还没有在 Wasm 中使用 Api 控制器对此进行测试。

在详细阅读了 aspnetcore 源代码和 MapFallbackToFile 之后,我想出了这个适合我的解决方案。我的服务器解决方案的 Startup.Configure 方法有这个:

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllers();
    endpoints.MapPost("{*path:nonfile}", CreatePostIndexRequestDelegate(endpoints));
    endpoints.MapFallbackToFile("index.html");
});

然后我将这个新方法添加到那个 Startup class:

//This method allows Post requests to non-file, non-api endpoints to return the index.html file
private static RequestDelegate CreatePostIndexRequestDelegate(IEndpointRouteBuilder endpoints)
{
    var app = endpoints.CreateApplicationBuilder();
    app.Use(next => context =>
    {
        context.Request.Path = "/index.html";
        context.Request.Method = "GET";
        // Set endpoint to null so the static files middleware will handle the request.
        context.SetEndpoint(null);
        return next(context);
    });
    app.UseStaticFiles();
    return app.Build();
}