1

アイデアは、次のように URL ごとにバージョン管理された API を持つことです。

  • /api/v1/天気予報
  • /api/v2/天気予報
  • /api/v3/天気予報

私の名前空間は次のとおりです。

名前空間のバージョニング

起動時に、バージョニングを登録するための次のコードがあります。

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddApiVersioning(
        options =>
        {
            // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
            options.ReportApiVersions = true;
            // automatically applies an api version based on the name of the defining controller's namespace
            options.Conventions.Add(new VersionByNamespaceConvention());
        });
}

だから私はすべてのコントローラーの"[Route("api/v{version:apiVersion}/[controller]")]"属性を削除したかったのですが、これは可能ですか?

次のようなものを使用してコントローラーをマップしようとしていました。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "api",
            pattern: "api/v{version:apiVersion}/{controller}/{id?}"
            );
    });
}

しかし、コードを実行すると、次のエラーが発生します。

アクション 'ApiVersioning.Api.V3.Controllers.WeatherForecastController.Get (ApiVersioning)' には属性ルートがありません。ApiControllerAttribute で注釈が付けられたコントローラーのアクション メソッドは、属性ルーティングされる必要があります。

では、すべてのコントローラーの上にある RouteAttribute の必要性をなくす、すべてのコントローラーに暗黙的なルーティング規則を追加することはできますか?

4

1 に答える 1

0

表示されるエラー メッセージは、組み込みの API Explorer の制限です。属性ルーティングのみをサポートします。ドキュメントにそれが必要ない場合は、問題にはなりません。

古い ASP.NET とは異なり、 UI コントローラーAPI コントローラーの間に区別はありません。ただし、開発者がそれらの間に期待する特定の動作があります。API のバージョニングでは、デフォルトの API バージョンを介して暗黙的に (および装飾されていない場合でも)、すべてのコントローラーがバージョン管理されている必要があります。この動作は、UI と API を混在させているユーザーにとっては望ましくありません。属性が導入される[ApiController]と、コントローラーが API 用であるかどうかを確実に識別する方法がついにありました。

これをテストするには、単純にApiVersioningOptions.UseApiBehavior = false. これにより、以前の動作に戻ります。これにより、すべてのコントローラーがバージョン管理されることに注意してください。

別のアプローチは、IApiControllerSpecificationまたはIApiControllerFilterを実装することです。フィルターはすべての仕様の集約であるため、通常はIApiControllerSpecificationのみが必要です。仕様またはフィルターを DI コンテナーに登録します。仕様の実装によって、 ControllerModelが指定された API 用のコントローラーであるかどうかが決まります。を探すビルトイン仕様があります[ApiController]基本クラスとしてControllerBaseを検索するものを作成するか、ルート テンプレートのプレフィックスや含まれる名前空間などの他のメカニズムを使用することができます。選択はあなた次第です。この仕様により、 を使用せずに独自の規則を使用できるようになります[ApiController]

1 つの場所で必要な属性を持つすべてのコントローラーの基本クラスを使用することもできます。標準のルート規則を使用する場合とまったく同じではありませんが、同様の結果が得られます。API ドキュメントをサポートする予定がある場合は、このアプローチが必要になる場合があります。

于 2020-09-16T21:21:48.207 に答える