質問:
ASP.NET MVC 6アプリケーションの同じコントローラーに2つの異なるルート(パラメーター付き)を割り当てる方法はありますか?
試した:
コントローラークラスと個々のアクションに複数のルート属性を使用しようとしましたが、機能しませんでした。
注:
ASP.NET Core 1.0 RC1を使用しています。
これを行う理由は、古いURLを使用するモバイルアプリの古いバージョンと互換性のあるAPIが必要だからです
例:
[Produces("application/json")]
[Route("api/v2/Log")]
/// The old route is "api/LogFile" which I want to be still valid for this controller.
public class LogController : Controller {
[HttpGet("{id}", Name = "download")]
public IActionResult GetFile([FromRoute] Guid id)
{
// ...
}
}
上記の例では:api/LogFile/{some-guid}
は古いルートであり、api/v2/log/download/{some-guid}
は新しいルートです。両方のルートで同じアクションを呼び出す必要があります。
新しいRC1アプリケーションでは、コントローラーレベルで2つのルート属性を使用すると正常に機能します。
[Produces("application/json")]
[Route("api/[controller]")]
[Route("api/old-log")]
public class LogController: Controller
{
[HttpGet]
public IActionResult GetAll()
{
return Json(new { Foo = "bar" });
}
}
両方 http://localhost:62058/api/log
およびhttp://localhost:62058/api/old-log
予想されるJSONを返します。私が見た唯一の注意点は、これらのアクションの1つにURLを生成する必要がある場合に備えて、属性の名前/順序のプロパティを設定することです。
アクションに2つの属性を設定することもできます:
[Produces("application/json")]
public class LogController : Controller
{
[Route("api/old-log")]
[Route("api/[controller]")]
[HttpGet]
public IActionResult GetAll()
{
return Json(new { Foo = "bar" });
}
}
ただし、コントローラレベルで一般的なルートを作成し、特定のアクションルートを作成する場合は注意が必要です。これらの場合、コントローラーレベルのルートはプレフィックスとして使用され、URLの前に追加されます(この動作についてのニースの記事があります here )。これにより、たとえば次のように、予想とは異なるURLのセットが取得される場合があります。
[Produces("application/json")]
[Route("api/[controller]")]
public class LogController : Controller
{
[Route("api/old-log")]
[Route("")]
[HttpGet]
public IActionResult GetAll()
{
return Json(new { Foo = "bar" });
}
}
アプリケーションが最後のケースでリッスンする2つのルートはhttp://localhost:62058/api/log
およびhttp://localhost:62058/api/log/api/old-log
以来api/log
は、アクションレベルで定義されたすべてのルートのプレフィックスとして追加されます。
最後に、別のオプションは、新しいルートの属性を使用してから、スタートアップクラスのルートテーブルを使用して、古いAPIを処理する特定のルートを提供することです。