web-dev-qa-db-ja.com

ASP.NETコア属性ルーティング

プロジェクトをaspnet coreに移行していますが、これらのルートを構成できませんでした。属性を使用してアクションをマップしています。

ASP.Net WebAPI2のコード

[Route("api/[controller]")]
public class SalesController : Controller
{
    // api/sales/1 -> ok
    [HttpGet]
    public HttpResponseMessage Get(int id)
    {
        // Logic
    }   

    // api/sales -> ok
    [HttpGet]
    public HttpResponseMessage Get([FromUri] PaginationHelper pagination)
    {
        // Logic
    }  

    // api/sales?me -> ok
    [ActionName("Get")]
    public HttpResponseMessage GetMe(bool? me)
    {
        // Logic
    }  
}

ASP.Net Coreのコード

ファイル内Startup.csが設定されていますapp.UseMvc();

[Route("api/[controller]")]
public class SalesController : Controller
{
    // api/sales/1 -> ok
    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        // Logic
    }   

    // api/sales -> don't work
    [HttpGet] // -> ???
    public IActionResult Get(PaginationHelper pagination)
    {
        // Logic
    }  

    // api/sales?me -> don't work
    [HttpGet] // -> ???
    public IActionResult GetMe(bool? me)
    {
        // Logic
    }  
}
7

たぶん私はこの議論に遅すぎるかもしれませんが、これは私がしたように、このページを読んでしまう他の人々にとって価値があるかもしれません。 APIエンドポイントの問題は、同じルートを処理するように2つのエンドポイントを構成したことです:_GET /api/sales_。

そのルートにアクセスしようとすると、フレームワークはGet(PaginationHelper)GetMe(bool?)を区別できなくなります。その理由は、両方に_[HttpGet]_属性があるためです。つまり、どちらも、クラス宣言のすぐ上にある[Route("api/[controller]")]属性で指定したルートを処理できます。それらは同じルートを処理できると宣言されているため、例外(_Multiple actions matched_)になります。

問題の解決策は、そのあいまいなルートを処理するアクションによって異なります。ルート_GET /api/sales_をGet(PaginationHelper)で処理する場合は、GetMe(bool?)アクションメソッドとその_[HttpGet]_属性を次のように変更できます。

_[HttpGet("me")] // GET api/sales/me
public IActionResult GetMe() {
    // Logic
}
_
6
Mladen B.

新しいフレームワークは、エンドポイントの意図をより明確に示すことを期待しています。

[Route("api/[controller]")]
public class SalesController : Controller {

    [HttpGet("{id:int}")] // GET api/sales/1
    public IActionResult Get(int id) {
        // Logic
    }

    [HttpGet] // GET api/sales?page=1 assuming PaginationHelper has page property
    public IActionResult Get([FromQuery]PaginationHelper pagination) {
        // Logic
    } 

    [HttpGet] // GET api/sales?me=true
    public IActionResult GetMe(bool? me = false) {
        // Logic
    }  
}

参照 Asp.Net Core:モデルバインディング

5
Nkosi

トークンを使用してルーティングを定義する非常にクリーンな方法があります。

以下では、コントローラーレベルの1つの場所でのみルートを定義しています。ここでの利点は、メソッド名をいつでも変更できることです。

[Route("[controller]/[action]")]
public class DepartmentsController : Controller
{
    public string List()
    {
        return "List() of DepartmentsController";
    }

    public string Details()
    {
        return "Details() of DepartmentsController";
    }
}
0
vivek nuna