惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
L
Lohrmann on Cybersecurity
P
Proofpoint News Feed
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
S
Schneier on Security
罗磊的独立博客
AWS News Blog
AWS News Blog
S
Securelist
J
Java Code Geeks
月光博客
月光博客
V
Vulnerabilities – Threatpost
博客园 - 【当耐特】
有赞技术团队
有赞技术团队
G
GRAHAM CLULEY
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
DataBreaches.Net
The Hacker News
The Hacker News
Know Your Adversary
Know Your Adversary
The GitHub Blog
The GitHub Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Scott Helme
Scott Helme
博客园 - Franky
S
Security Affairs
Cyberwarzone
Cyberwarzone
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Forbes - Security
Forbes - Security
K
Kaspersky official blog
Martin Fowler
Martin Fowler
Schneier on Security
Schneier on Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
宝玉的分享
宝玉的分享
腾讯CDC
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
美团技术团队
MyScale Blog
MyScale Blog
L
LangChain Blog
V
V2EX
N
News | PayPal Newsroom
N
News and Events Feed by Topic
aimingoo的专栏
aimingoo的专栏
Blog — PlanetScale
Blog — PlanetScale
IT之家
IT之家

博客园 - laughter

使用Using的注意事项 [转]VMPlayer的Briged网络配置 [转]移动互联网应用技术架构简介-Restful服务 理解WCF中的Contracts [翻译]在ASP.NET Web API中通过OData支持查询和分页 [转]NBehave行为驱动测试关于story和scenarios [转]使用TeamCity对项目进行可持续集成管理(一) [转]SpecFlow使用入门 [转]软件测试- 3 - Mock 和Stub的区别 [翻译]创建ASP.NET WebApi RESTful 服务(11) [翻译]创建ASP.NET WebApi RESTful 服务(10) [翻译]创建ASP.NET WebApi RESTful 服务(9) [转]模拟HttpContext 实现ASP.NET MVC 的单元测试 [翻译]创建ASP.NET WebApi RESTful 服务(8) [转]软件开发过程(CMMI/RUP/XP/MSF)是与非? [转]比较 Rational Unified Process (RUP) 和 Microsoft Solutions Framework (MSF) [翻译]Behavior-Driven Development (BDD)行为驱动开发(二) [翻译]Behavior-Driven Development (BDD)行为驱动开发(一) 【Visual Studio2010】创建XAML分析插件
[翻译]创建ASP.NET WebApi RESTful 服务(7)
laughter · 2014-04-13 · via 博客园 - laughter

实现资源分页

本章我们将介绍几种不同的结果集分页方式,实现手工分页,然后将Response通过两个不同的方式进行格式化(通过Response的Envelop元数据或header)。

大家都知道一次查询返回几百条数据是很讨厌的事情,那么在WebApi中分页就更有必要。

手动分页和封装

接下来我们修改CoursesController来实现分页而不是返回所有数据。

   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/