Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Pagination to Link Headers in Web Api 2

Currently in my Rest service I return paged data using the model that follows.

public class PagedResults<T>
{
    public List<LinkModel> Links { get; set; }
    public int TotalCount { get; set; }
    public double TotalPages { get; set; }
    public List<T> Results { get; set; }
}

This works alright, but I came across the following post.

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#pagination

My curiosity was peaked, it mentions using the HTTP headers to return links and pagination information. Although the post mentions RFC 5988, I was unable to unravel what that really means? Was it every actually adopted as a standard of some sort?

The question here is in ASP.Net Web API 2, is there any support for adding pagination information in the link header? I used intellisense to peruse HTTP response headers and I did not find Links, or anything similar.

I found this post, but it doesn't really answer my question of ease of doing this in Web API 2.

Link headers vs link elements for RESTful JSON

like image 942
GetFuzzy Avatar asked Sep 28 '14 01:09

GetFuzzy


2 Answers

You can check my post here which shows how to add pagination as "custom" (X-Pagination) header, below is sample code that might help:

 public IEnumerable<StudentBaseModel> Get(int page = 0, int pageSize = 10)
{
    IQueryable<Student> query;

    query = TheRepository.GetAllStudentsWithEnrollments().OrderBy(c => c.LastName);

    var totalCount = query.Count();
    var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

    var urlHelper = new UrlHelper(Request);
    var prevLink = page > 0 ? urlHelper.Link("Students", new { page = page - 1, pageSize = pageSize }) : "";
    var nextLink = page < totalPages - 1 ? urlHelper.Link("Students", new { page = page + 1, pageSize = pageSize }) : "";

    var paginationHeader = new
    {
        TotalCount = totalCount,
        TotalPages = totalPages,
        PrevPageLink = prevLink,
        NextPageLink = nextLink
    };

    System.Web.HttpContext.Current.Response.Headers.Add("X-Pagination",
    Newtonsoft.Json.JsonConvert.SerializeObject(paginationHeader));

    var results = query
    .Skip(pageSize * page)
    .Take(pageSize)
    .ToList()
    .Select(s => TheModelFactory.CreateSummary(s));

    return results;
}
like image 198
Taiseer Joudeh Avatar answered Oct 13 '22 18:10

Taiseer Joudeh


In .Net MVC adding Link headers is trivial. According to the IETF they get separated by comma, so:

HttpContext.Response.Headers.Add("Link", string.Join(",", pagedResult.Links));

Note: that pagedResult is in an instance of your PagedResult<T> class.

This can be used in conjunction with Taiseer's X-Pagination headers above.

like image 36
pim Avatar answered Oct 13 '22 18:10

pim