web-dev-qa-db-ja.com

ASP .NET Core Web APIでフォールバックをマップして、Blazor WASMアプリがAPI以外のリクエストのみをインターセプトするようにする方法

Microsoftのデフォルトのソリューションテンプレートに基づいて、クライアントプロジェクト、サーバープロジェクト、共有プロジェクトを含むBlazor WebAssemblyソリューションがあります。 Google ChromeでVisual Studio 2019プレビューを編集してデバッグしています。

箱から出してすぐのソリューションには、サーバーアプリケーションである単一のスタートアッププロジェクトがあります。そのサーバーアプリケーションには、クライアントアプリケーションへのプロジェクト参照があります。サーバープロジェクトのプロパティで[SSLを有効にする]をオンにすると、HTTPSを使用するように設定できます。

デバッグをクリックすると完全に機能します。

Blazor WASMアプリが https:// localhost:44331 からのリクエストにのみ応答し、 https:// localhost:44331/api へのリクエストに応答しないように変更します=。これらのリクエストは、代わりにサーバーアプリケーションのAPIコントローラエンドポイントで処理する必要があります。したがって、誰かが https:// localhost:44331/api/something にアクセスし、そのようなAPIエンドポイントが存在しない場合、APIから404エラーコードを受け取り、通常のBlazorページにルーティングされないはずです。 「申し訳ありません、この住所には何もありません。」

URLのこの追加の「/ api」部分を使用して、APIへのリクエストをページのリクエストから分離します。これは、通常のセットアップが本番環境でどのようになるかにより近いと思います。私がやろうとしていることが明確であることを願っています。

以下は、ルート属性を使用したサンプルのコントローラー宣言です。

namespace BlazorApp2.Server.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        // Etc.

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            //etc.
        }
///etc.
    }
}

Startup.csで試してみましたが、機能しません。誰かが喜ばせる何かを提案できますか?

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Etc.
    app.UseStatusCodePages();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllers();
        // The line commented out below is the out-of-the-box behaviour for a Blazor WASM app with ASP NET Core API. This is the line I want to replace.
        // endpoints.MapFallbackToFile("index.html");

        // The line below is my (failed) attempt to get the behaviour I want.
        endpoints.MapFallback(HandleFallback);
    });
}

private async Task HandleFallback(HttpContext context)
{
    var apiPathSegment = new PathString("/api"); // Find out from the request URL if this is a request to the API or just a web page on the Blazor WASM app.

    bool isApiRequest = context.Request.Path.StartsWithSegments(apiPathSegment);

    if (!isApiRequest)
    {
        context.Response.Redirect("index.html"); // This is a request for a web page so just do the normal out-of-the-box behaviour.
    }
    else
    {
        context.Response.StatusCode = StatusCodes.Status404NotFound; // This request had nothing to do with the Blazor app. This is just an API call that went wrong.
    }
}

誰かがこれをどのように機能させるか知っていますか?

3
benjamin

これがうまくいくはずです:

endpoints.MapFallbackToPage("{*path:regex(^(?!api).*$)}", "index.html"); // don't match paths beginning with api

パスがapiで始まらないURLのみに一致するようなものだと思います。

0
Darragh

Blazor WASMがホストするソリューションから開始する場合、サンプルを取得し、起動するだけです

dotnet new blazorwasm --hosted

3つのプロジェクトでソリューションを作成します。

|-クライアント
|-サーバー
|-共有

Server Startupクラスでは、ミドルウェアパイプラインは次のように設定されています。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseWebAssemblyDebugging();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseBlazorFrameworkFiles();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapFallbackToFile("index.html");
    });
}

コントローラは、ルートを Route 属性で定義します。 / api/{controller}でコントローラーをホストする場合は、Route属性値api/[controller]を使用します。

[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
0
agua from mars