首页 > 解决方案 > 如何为 Blazor MapFallbackToFile() 生成正确的错误

问题描述

我有一个项目我想用作 Web API 和 Blazor wasm UI。这个 API 也可以从其他项目访问,所以我希望 API 向消费者提供有用的错误详细信息。

我现在通过使用该MapFallbackToFile()方法使该站点同时实现这两个目的,但是如果您尝试对POST仅接受的端点进行 a GET,您将得到404响应,而不是405无效的 http 方法。

我正在使用此问题中提供的解决方案来仅映射非 api 路径,但这总是给出 404,我担心它会隐藏请求的任何其他潜在问题。

我怎样才能让该HandleApiFallback()方法像通常的 Web API 一样简单地运行,同时仍然/api/从服务 blazor 页面中排除路径?


app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllers();
    endpoints.Map("api/{**slug}", HandleApiFallback);
    endpoints.MapFallbackToFile("{**slug}", "index.html");
});

private Task HandleApiFallback(HttpContext context)
{
    context.Response.StatusCode = StatusCodes.Status404NotFound;
    return Task.CompletedTask;
}

示例集成测试:

    var response = client.GetAsync(path).GetAwaiter().GetResult();
    response.StatusCode.Should().Be(HttpStatusCode.OK);

    var response2 = client.PostAsJsonAsync(path, "").GetAwaiter().GetResult();
    response2.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed);

当你有任何MapFallbackToFile()使用时,第二个断言作为 404 而不是 405 失败。

标签: c#asp.net-core-webapiblazor-webassembly

解决方案


我通过查看您可能希望在不同处运行多个 blazor 应用程序的案例找到了一个解决方案,并对其进行了修改以适合我的用例:


//explicitly only use blazor when the path doesn't start with api
app.MapWhen(ctx => !ctx.Request.Path.StartsWithSegments("/api"), blazor =>
{
    blazor.UseBlazorFrameworkFiles();
    blazor.UseStaticFiles();

    blazor.UseRouting();
    blazor.UseEndpoints(endpoints =>
    {
        endpoints.MapFallbackToFile("index.html");
    });
});

//explicitly map api endpoints only when path starts with api
app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/api"), api =>
{
    //if you are not using a blazor app, you can move these files out of this closure
    api.UseStaticFiles();
    api.UseRouting();
    api.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
    });
});

这通过了我提到的集成测试,因此405当我尝试对 API 使用错误的 HTTP 方法而不是404.


推荐阅读