web-dev-qa-db-ja.com

ASP MVC 6で同じコントローラーまたはアクションに複数のルートを割り当てる

質問:

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}は新しいルートです。両方のルートで同じアクションを呼び出す必要があります。

31
A-Sharabiani

新しい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を処理する特定のルートを提供することです。

52
Daniel J.G.