本章我们将介绍几种不同的结果集分页方式,实现手工分页,然后将Response通过两个不同的方式进行格式化(通过Response的Envelop元数据或header)。
大家都知道一次查询返回几百条数据是很讨厌的事情,那么在WebApi中分页就更有必要。
接下来我们修改CoursesController来实现分页而不是返回所有数据。
class="alt"> 1: public Object Get(int page = 0, int pageSize = 10)
   2:      {   3:          IQueryable<Course> query;   4:      5:          query = TheRepository.GetAllCourses().OrderBy(c => c.CourseSubject.Id);   6:          var totalCount = query.Count();7: var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
   8:   9: var urlHelper = new UrlHelper(Request);
10: var prevLink = page > 0 ? urlHelper.Link("Courses", new { page = page - 1 }) : "";
11: var nextLink = page < totalPages - 1 ? urlHelper.Link("Courses", new { page = page + 1 }) : "";
  12:     13:          var results = query  14:          .Skip(pageSize * page)  15:          .Take(pageSize)  16:          .ToList()  17:          .Select(s => TheModelFactory.Create(s));  18:   19: return new
  20:          {  21:              TotalCount = totalCount,  22:              TotalPages = totalPages,  23:              PrevPageLink = prevLink,  24:              NextPageLink = nextLink,  25:              Results = results  26:          };  27:     28:      }
代码很简单,添加两个可选参数,它们最终会被格式化为QueryString。例如http://localhost:{your_port}/api/courses/?page=1代表你需要访问第一页的10条数据。不出意外,结果可能是这样的:
   1:  {   2:   3: "totalCount": 33,
4: "totalPages": 4,
5: "prevPageLink": "http://localhost:8323/api/courses?page=0&pageSize=10",
6: "nextPageLink": "http://localhost:8323/api/courses?page=2&pageSize=10",
7: "results": [ /* Array containts the results*/ ]
   8:      9:  }
结果是我们通过将数据封装为json通过Response的结果返回,这样记录总数也可以被返回。一个明显的缺点是这种类似的数据可能会污染我们期望的结果集,所以接下来我们通过在Response Header中添加一个X-Pagination参数来实现这一功能。
通过Response Header实现分页
实现代码如下:
1: public IEnumerable<StudentBaseModel> Get(int page = 0, int pageSize = 10)
   2:      {   3:          IQueryable<Student> query;   4:      5:          query = TheRepository.GetAllStudentsWithEnrollments().OrderBy(c => c.LastName);   6:      7:          var totalCount = query.Count();8: var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
   9:   10: var urlHelper = new UrlHelper(Request);
11: var prevLink = page > 0 ? urlHelper.Link("Students", new { page = page - 1, pageSize = pageSize }) : "";
12: var nextLink = page < totalPages - 1 ? urlHelper.Link("Students", new { page = page + 1, pageSize = pageSize }) : "";
  13:   14: var paginationHeader = new
  15:          {  16:              TotalCount = totalCount,  17:              TotalPages = totalPages,  18:              PrevPageLink = prevLink,  19:              NextPageLink = nextLink  20:          };  21:   22: System.Web.HttpContext.Current.F.Add("X-Pagination",
  23:          Newtonsoft.Json.JsonConvert.SerializeObject(paginationHeader));  24:     25:          var results = query  26:          .Skip(pageSize * page)  27:          .Take(pageSize)  28:          .ToList()  29:          .Select(s => TheModelFactory.CreateSummary(s));  30:   31: return results;
  32:      }
需要注意代码中,我们在Response.Headers中添加了一个通过json序列化的分页参数。这样返回结果及就可以直接被使用,无法再考虑额外的信息。
来源:http://bitoftech.net/2013/11/25/implement-resources-pagination-asp-net-web-api/
 相关文章
                            相关文章