何度も試して記事を読んだ後、私の問題をここに置くことにしました。私が欲しいのは次のとおりです。アプリケーションの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
。このために、私はこれらの記事に従いました:
- https://stevenknox.net/aspnet-core-mvc-action-priority-using-actionconstraints/
- https://www.strathweb.com/2017/06/using-iactionconstraints-in-asp-net-core-mvc/
次に、次のクラスを作成しました。
[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.Versioning
api-version 1.1
HttpRequestPriority
3番目: MapSpaFallbackRoute
inStartup.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
ですか? 前もって感謝します!