4

何度も試して記事を読んだ後、私の問題をここに置くことにしました。私が欲しいのは次のとおりです。アプリケーションのAPIバージョン管理に取り組んでいます。.NET Core (Microsoft.AspNetCore.Mvc.Versioningパッケージ) でサポートされているバージョン形式は Major.Minor であり、これは私が取り組んでいるプロジェクトで使用したいものです。私が欲しいのは、クライアントによってマイナー バージョンが指定されていない場合のフォールバック バージョンです。私は.NETコア2.2を使用api-versionしており、ヘッダーで指定されています。対応する API バージョニング構成は次のようになります。

    services.AddApiVersioning(options => { 
        options.ReportApiVersions = true;
        options.ApiVersionReader = new HeaderApiVersionReader("api-version");
        options.ErrorResponses = new ApiVersioningErrorResponseProvider();
    });

各バージョンに次の 2 つのコントローラーがあります: (コントローラーは、この SO の質問のために単純化されています):

[ApiVersion("1.0")]  
[Route("api/[controller]")]  
public class ValueControllerV10 : Controller  
{  
    [HttpGet(Name = "collect")]  
    public String Collect()  
    {  
        return "Version 1.0";  
    }  
} 


[ApiVersion("1.1")]  
[Route("api/[controller]")]  
public class ValueControllerV11 : Controller  
{  
    [HttpGet(Name = "collect")]  
    public String Collect()  
    {  
        return "Version 1.1";  
    }  
}  

クライアントが指定api-version=1.0した場合、ValueControllerV10 が使用されます。もちろん、クライアントが を指定した場合api-version=1.1は、予想どおり、ValueControllerV11 が使用されます。

そして今、私の問題があります。クライアントが指定した場合api-version=1(マイナー バージョンを含まないメジャー バージョンのみ)、ValueControllerV10 が使用されます。私が間違っていなければ、はApiVersion.Parse("1")に等しいからです。ApiVersion.Parse("1.0")しかし、この場合に必要なのは、指定されたメジャー バージョンの最新バージョン (この例では 1.1) を呼び出すことです。

私の試み:

最初:[ApiVersion("1")]で指定ValueControllerV11

    [ApiVersion("1")]  
    [ApiVersion("1.1")]  
    [Route("api/[controller]")]  
    public class ValueControllerV11 : Controller  
    {  
        [HttpGet(Name = "collect")]  
        public String Collect()  
        {  
            return "Version 1.1";  
        }  
    }  

それは機能しません、それはつながります

AmbiguousMatchException: The request matched multiple endpoints

これを解決するために、私は 2 番目のアプローチを思い付きました。

2 番目: カスタムを使用しますIActionConstraint。このために、私はこれらの記事に従いました:

次に、次のクラスを作成しました。

[AttributeUsage(AttributeTargets.Method)]
public class HttpRequestPriority : Attribute, IActionConstraint
{
    public int Order
    {
        get
        {
            return 0;
        }
    }

    public bool Accept(ActionConstraintContext context)
    {
        var requestedApiVersion = context.RouteContext.HttpContext.GetRequestedApiVersion();

        if (requestedApiVersion.MajorVersion.Equals(1) && !requestedApiVersion.MinorVersion.HasValue)
        {
            return true;
        }

        return false;
    }
}

そしてで使用されValueControllerV11ます:

[ApiVersion("1")]  
[ApiVersion("1.1")]  
[Route("api/[controller]")]  
public class ValueControllerV11 : Controller  
{  
    [HttpGet(Name = "collect")]
    [HttpRequestPriority]  
    public String Collect()  
    {  
        return "Version 1.1";  
    }  
}

まあ、それは を解決しますが、パッケージAmbiguousMatchExceptionのデフォルトの動作をオーバーライドするので、クライアントが を使用すると、404 Not Found が返されます。これは、の実装に従って理解できます。Microsoft.AspNetCore.Mvc.Versioningapi-version 1.1HttpRequestPriority

3番目: MapSpaFallbackRouteinStartup.csを条件付きで使用:

        app.MapWhen(x => x.GetRequestedApiVersion().Equals("1") && x.GetRequestedApiVersion().MinorVersion == null, builder =>
        {
            builder.UseMvc(routes =>
            {
                routes.MapSpaFallbackRoute(
                    name: "spa-fallback",
                    defaults: new {controller = nameof(ValueControllerV11), action = "Collect"});
            });
        });

        app.UseMvc();

どちらも機能しません。影響はありません。その名前MapSpaFallbackRouteは、私が使用する必要があるものではないという気持ちも与えます...

だから私の質問は次のとおりです。マイナーバージョンが指定されていない場合に、フォールバックの「最新のものを使用」動作を導入するにはどうすればよいapi-versionですか? 前もって感謝します!

4

3 に答える 3