实现资源分页

本章我们将介绍几种不同的结果集分页方式,实现手工分页,然后将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:      }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

代码很简单,添加两个可选参数,它们最终会被格式化为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:      }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

需要注意代码中,我们在Response.Headers中添加了一个通过json序列化的分页参数。这样返回结果及就可以直接被使用,无法再考虑额外的信息。

来源:http://bitoftech.net/2013/11/25/implement-resources-pagination-asp-net-web-api/

[翻译]创建ASP.NET WebApi RESTful 服务(7)的更多相关文章

  1. [翻译]创建ASP.NET WebApi RESTful 服务(8)

    本章讨论创建安全的WebApi服务,到目前为止,我们实现的API都是基于未加密的HTTP协议,大家都知道在Web中传递身份信息必须通过HTTPS,接下来我们来实现这一过程. 使用HTTPS 其实可以通 ...

  2. [翻译]创建ASP.NET WebApi RESTful 服务(11)

    本章介绍通过使用Ali Kheyrollahi开发的CacheCow来实现服务器端的缓存.所有代码现在都可以在GitHub上下载. 我们将要实现的缓存方式叫做Conditional Requests, ...

  3. [翻译]创建ASP.NET WebApi RESTful 服务(9)

    一旦成功的发布API后,使用者将依赖于你所提供的服务.但是变更总是无法避免的,因此谨慎的制定ASP.NET Web API的版本策略就变得非常重要.一般来说,新的功能需要无缝的接入,有时新老版本需要并 ...

  4. [翻译]创建ASP.NET WebApi RESTful 服务(10)

    通过URI实现版本管理 另一种实现版本管理的方式就是通过URI来进行处理,类似于http://localhost:{your_port}/api/v1/students/.这种方式的好处是使用者可以清 ...

  5. IIS 部署ASP.Net, WebAPI, Restful API, PUT/DELETE 报405错解决办法, webapi method not allowed 405

    WebDAV 是超文本传输协议 (HTTP) 的一组扩展,为 Internet 上计算机之间的编辑和文件管理提供了标准.利用这个协议用户可以通过Web进行远程的基本文件操作,如拷贝.移动.删除等.在I ...

  6. Asp.net WebAPi Restful 的实现和跨域

    现在实际开发中用webapi来实现Restful接口开发很多,我们项目组前一段时间也在用这东西,发现大家用的还是不那么顺畅,所以这里写一个Demo给大家讲解一下,我的出发点不是如何实现,而是为什么? ...

  7. 在windows10上创建ASP.NET mvc5+Memcached服务

    感谢两位两位大佬: https://blog.csdn.net/l1028386804/article/details/61417166 https://www.cnblogs.com/running ...

  8. ASP.NET WebAPI 双向token实现对接小程序登录逻辑

    最近在学习用asp.net webapi搭建小程序的后台服务,因为基于小程序端和后台二者的通信,不像OAuth(开放授权),存在第三方应用.所以这个token是双向的,一个是对用户的,一个是对接口的. ...

  9. [03-2]VS2017 创建 ASP.NET Core Web 程序

    VS2017 创建 ASP.NET Core Web 程序 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自<从零开始学 ...

随机推荐

  1. android开发找不到模拟器(PANIC: Could not open:)解决办法

    android开发找不到模拟器(PANIC: Could not open:)解决办法   2013/4/3 17:44:15 0人评论 213次浏览 分类:android开发 在系统环境变量设置名为 ...

  2. linux下从源代码安装git

    之所以有这样的需求,是因为部分预安装的git版本太低,很多功能没有并且安全性存在问题. 比如git submodule add xxx@host:yyy.git必须在父repo的root目录安装,而新 ...

  3. 51nod1239 欧拉函数之和

    跟1244差不多. //由于(x+1)没有先mod一下一直WA三个点我... //由于(x+1)没有先mod一下一直WA三个点我... #include<cstdio> #include& ...

  4. KVC&KVO&NSNotification

    KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性.KVO 就是基于 KVC 实现的关键技术之一. 一个对象拥有某些属性.比如说,一个 ...

  5. vim 大小写转化命令

    vim中大小写转化的命令是<blockquote>gu或者gU</blockquote>形象一点的解释就是小u意味着转为小写:大U意味着转为大写. 剩下的就是对这两个命令的限定 ...

  6. 实现输出h264直播流的rtmp服务器

    RTMP(Real Time Messaging Protocol)是常见的流媒体协议,用来传输音视频数据,结合flash,广泛用于直播.点播.聊天等应用,以及pc.移动.嵌入式等平台,是做流媒体开发 ...

  7. Android 动画 6问6答

    1.view 动画有哪些需要注意的? 答:view动画 本身比较简单.http://www.cnblogs.com/punkisnotdead/p/5179115.html 看这篇文章的第五问就可以了 ...

  8. windows xp 安装mysql5.6.17-ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password

    .zip解压后没有setup 没有my.ini 1.安装方法 bin目录下执行以下: E:\mysql-5.6.17-win32\bin>mysqld install MySQL --defau ...

  9. git常用知识整理

    分布式和集中版本控制的区别 分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因 ...

  10. phonegap 使用极光推送实现消息推送

    最近一直在研究各种推送,ios的由于是apns,比较容易实现,但是andriod的就比较麻烦.后来看了很多解决方案,gcm明显是不行的,其他的方案更是一头雾水,而且需要做第二次开发,太麻烦,后来就选择 ...