3

I want to return the current pages and total pages form a generic method.

The implementation of the generic function is done as:

public class PaginatedList<T> : List<T>
{
    public int PageIndex { get; set; }
    public int TotalPages { get; set; }

    public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalPages = (int)Math.Ceiling(count / (double)pageSize);

        this.AddRange(items);
    }

    public bool HasPreviousPage
    {
        get
        {
            return (PageIndex > 1);
        }
    }

    public bool HasNextPage
    {
        get
        {
            return (PageIndex < TotalPages);
        }
    }
    public static async Task<PaginatedList<T>> CreateAsync(
       IQueryable<T> source, int pageIndex, int pageSize)
    {
        var count = await source.CountAsync();
        var items = await source.Skip(
            (pageIndex - 1) * pageSize)
            .Take(pageSize).ToListAsync();
        return new PaginatedList<T>(items, count, pageIndex, pageSize);
    }
}

However, this function does not return the PageIndex and TotalPages to the calling function.

It always returns the items list.

I am calling the method as:

public async Task<IActionResult> UserActivityList(string currentFilter,
    string searchString, int? pageIndex, int pageSize = 10)
{
    if (searchString != null)
    {
        pageIndex = 1;
    }
    else
    {
        searchString = currentFilter;
    }

    string CurrentFilter = searchString;


    IQueryable<UserActivityList> results = _logContext.UserActivityLists;

    if (!string.IsNullOrEmpty(searchString))
    {
        results = results.Where(s => s.Name.Contains(searchString));
    }


    var UserActivityLists = await PaginatedList<UserActivityList>.CreateAsync(results.AsNoTracking(), pageIndex ?? 1, pageSize);

    return Ok(UserActivityLists);
}

The value of UserActivityList, I have formatted the output to JSON, while am calling through a PostMan.

[
    {
        "id": 2186,
        "name": "abc cbc"
    },
    {
        "id": 2152,
        "name": "def efg"
    },
    {
        "id": 2238,
        "name": "kgh tbf"
    },
    {
        "id": 2172,
        "name": "loc tbh"
    },
    {
        "id": 1651,
        "name": "abc abc"
    }
]

What is the reason the PaginatedList not returning other property? What is the thing I am missing here?

Aakash Bashyal
  • 316
  • 1
  • 9

2 Answers2

4

This is due to the serializer just seeing an IEnumerable<T> and doing it's (default) thing. Can I suggest that your class does not inherit from List<T> as it should not have an is-a relationship - it should be a has-a relationship which means your PaginatedList should expose a List<T> (or IEnumerable<T>) property.

With this change you can more exactly control how serialization of your object is handled.

public class PaginatedList<T> 
{
    public int PageIndex { get; set; }
    public int TotalPages { get; set; }
    public List<T> Items { get; set; }

    public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalPages = (int)Math.Ceiling(count / (double)pageSize);
        Items = items;
    }

    public bool HasPreviousPage
    {
        get
        {
            return (PageIndex > 1);
        }
    }

    public bool HasNextPage
    {
        get
        {
            return (PageIndex < TotalPages);
        }
    }
    public static async Task<PaginatedList<T>> CreateAsync(
       IQueryable<T> source, int pageIndex, int pageSize)
    {
        var count = await source.CountAsync();
        var items = await source.Skip(
            (pageIndex - 1) * pageSize)
            .Take(pageSize).ToListAsync();
        return new PaginatedList<T>(items, count, pageIndex, pageSize);
    }
}
Jamiec
  • 118,012
  • 12
  • 125
  • 175
0

There is this good question/answer about inheriting from List<T>: Why not inherit from List<T>?

A very simple solution is of course to refactor your code so that you do not inherit form List, but expose a List as a property:

public class Document<T> 
{
    public int PageIndex { get; private set; }
    public int TotalPages { get; private set;}
    public List<T> Pages {get; private set; }

    public Document(List<T> items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalPages = (int)Math.Ceiling(count / (double)pageSize);

        this.Pages = new List<T>(items);
    }
    // ...
}
oerkelens
  • 4,600
  • 1
  • 19
  • 28