web-dev-qa-db-ja.com

.NET Core Web APIルートテンプレートのオプションパラメーター

_[HttpGet("{pageNumber}{pageSize?}{filter?}{sortOrder?}", Name = "GetEntriesPaged")]
public ActionResult<List<Entry>> GetEntriesPaged(
    int pageNumber, int pageSize = 10, string filter = "", string sortOrder = "desc") {
_

実行時例外:

System.ArgumentException:オプションのパラメーターはセグメントの最後になければなりません。セグメント「{pageNumber} {pageSize?} {filter?} {sortOrder?}」では、オプションのパラメーター「pageSize」の後に「filter」が続きます。パラメーター名:routeTemplate

ポイントは?質問のとおり、セグメントの最後にオプションのパラメーターがあります。

PS。より完全なコード:

_[HttpGet]
public ActionResult<List<Entry>> GetAll() {
    var result = _db.Entries.OrderByDescending(x => x.Date).ToList();
    return result;
}

[HttpGet("{pageNumber}{pageSize?}{filter?}{sortOrder?}", Name = "GetEntriesPaged")]
public ActionResult<List<Entry>> GetEntriesPaged(int pageNumber = 1, int pageSize = 10, string filter = "", string sortOrder = "desc") {
    int take = pageSize;
    int skip = ((pageNumber - 1) * pageSize);
    IQueryable<Entry> result;

    if (sortOrder == "asc") {
        result = _db.Entries.OrderBy(x => x.Date);
    }
    else {
        result = _db.Entries.OrderByDescending(x => x.Date);
    }

    return result.Skip(skip).Take(take).Where(x => x.Origin.Contains(filter)).ToList();
}

[HttpGet("{id}", Name = "GetEntry")]
public ActionResult<Entry> GetById(long id) {
    var item = _db.Entries.Find(id);
    if (item == null) {
        return NotFound();
    }
    return item;
}
_

_/entries_ GetAll()メソッドを使用する必要がありますが、_/esntries?pageNumber=3_ GetEntriesPaged(...) one

5
Serge

いいえ、あなたはしません。 sortOrderは末尾にありますが、pageSizefilterは末尾にありません。つまり、このような複数のオプションパラメータを持つことはできません。作成されるルートの組み合わせが多すぎるため、リクエストのルーティング方法や、満たすべき特定のルートパラメータを決定できなくなります。たとえば、pageSizesortOrderを入力し、filterを入力しないとどうなりますか? ASP.NET Coreは、あなたがsortOrderに提供したものが実際にfilterを意図したものではないことを知っているはずです。

FWIW、これらのルートパラメータ間にはスラッシュも必要です。そうでなければ、どこで終わり次が始まるかを知る方法がありません。たとえば、/111サイズが11のページ1、サイズが1のページ11、またはページ111で、サイズが設定されていないということですか?しかし、それでもそれらをすべてオプションにすることはできません。

URLに複数のオプション項目が必要な場合は、クエリ文字列を使用してそれらを提供するのが最善です。

[〜#〜] update [〜#〜]

あなたはページングのために複数のアクションを必要としないし、本当にすべきではありません。一般的な機能が多すぎるため、その差はわずかです。典型的な式は次のとおりです。

public async Task<IActionResult> GetAll(int? page = null, int pageSize = 10)
{
    var query = _context.Foos;
    if (page.HasValue)
    {
        query = query.Skip((page.Value - 1) * pageSize).Take(pageSize);
    }

    return Ok(await query.ToListAsync());
}
5
Chris Pratt