生成第一个/下一个/上一个/最后一个链接,其中api仅提供偏移量

时间:2019-03-07 11:50:26

标签: c# asp.net

我正在尝试编写一些带有offset值的代码,然后生成第一个/下一个/上一个/最后一个链接。

我目前有类似以下内容,但请继续考虑一些极端情况,而我的计算会出现偏差。我认为某人一定已经在某处完成了此操作,但是找不到可以查看/使用的库。

public class PagedItems<T>
{
    public PagedItems()
    {
    }

    public PagedItems(int offset, int totalSize, IEnumerable<T> subset)
    {
        this.Offset = offset;
        this.TotalSize = totalSize;
        this.Data = subset;
        this.Links = new Dictionary<string, Uri>();

        var pageCount = (totalSize - offset) / 20;

        if (offset > 20)
        {
            this.Links.Add("prev", new Uri($"/accounts?skip={offset - 20}"));
        }

        if (offset < (totalSize - offset))
        {
            this.Links.Add("last", new Uri($"/accounts/skip={totalSize - 20}"));
        }
    }

    public int Offset { get; }

    public int Size => this.Data.Count();

    public int TotalSize { get; }

    public IEnumerable<T> Data { get; }

    public Dictionary<string, Uri> Links { get; }
}

1 个答案:

答案 0 :(得分:0)

对于任何想要这个的人,我都可以使用此代码并围绕逻辑进行单元测试:

public class PagedItems<T>
{
    private readonly int pageSize;

    public PagedItems()
    {
    }

    public PagedItems(int offset, int pageSize, int totalSize, IEnumerable<T> subset, Uri baseUri)
    {
        this.Offset = offset;
        this.pageSize = pageSize;
        this.TotalSize = totalSize;
        this.Data = subset;
        this.Links = new Dictionary<string, string>();

        if (ShouldDisplayPrevAndFirstLink(offset))
        {
            var linkValue = Math.Max(offset - pageSize, 0);

            var link = QueryHelpers.AddQueryString(baseUri.OriginalString, "skip", linkValue.ToString());

            this.Links.Add("prev", link);
        }

        if (ShouldDisplayNextAndLastLink(offset, totalSize, pageSize))
        {
            var linkValue = offset + pageSize;

            var link = QueryHelpers.AddQueryString(baseUri.OriginalString, "skip", linkValue.ToString());

            this.Links.Add("next", link);
        }

        if (ShouldDisplayPrevAndFirstLink(offset))
        {
            var link = QueryHelpers.AddQueryString(baseUri.OriginalString, "skip", "0");

            this.Links.Add("first", link);
        }

        if (ShouldDisplayNextAndLastLink(offset, totalSize, pageSize))
        {
            var linkValue = totalSize - pageSize;

            var link = QueryHelpers.AddQueryString(baseUri.OriginalString, "skip", linkValue.ToString());

            this.Links.Add("last", link);
        }
    }

    private static bool ShouldDisplayNextAndLastLink(int offset, int totalSize, int pageSize) => offset < totalSize - pageSize;

    private static bool ShouldDisplayPrevAndFirstLink(int offset) => offset > 0;

    public int Offset { get; }

    public int Size => this.Data.Count();

    public int TotalSize { get; }

    public IEnumerable<T> Data { get; }

    public Dictionary<string, string> Links { get; }
}