GetFuzzy
GetFuzzy

Reputation: 2158

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

Upvotes: 8

Views: 15091

Answers (2)

pim
pim

Reputation: 12597

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.

Upvotes: 2

Taiseer Joudeh
Taiseer Joudeh

Reputation: 9043

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;
}

Upvotes: 15

Related Questions