使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【七】——实现资源的分页
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html
前言
这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可能会在系列的后期介绍,还没确定。。。),对于分页的结果,我们将采用2种不同的方式响应给客户端(1.将分页元数据封装在响应Body中2.在http响应报文头部添加分页信息)。
众所周知,在服务器端一次性返回成百上千条数据是非常恐怖的,在我们设计Api的时候,对于Get方法我们应该以分页的方式返回。例如:每次响应给客户端10条数据,并且包含“上一页”和“下一页”的标签,这样用户就能去获得他想要的数据。
Way1.封装分页元数据封装在响应Body中
修改“CoursesController”的Get方法实现分页而不是一次性把所有数据返回,下面上代码:
public Object Get(int page = , int pageSize = )
{
IQueryable<Course> query; query = TheRepository.GetAllCourses().OrderBy(c => c.CourseSubject.Id);
var totalCount = query.Count();
var totalPages = (int)Math.Ceiling((double)totalCount / pageSize); var urlHelper = new UrlHelper(Request);
var prevLink = page > ? urlHelper.Link("Courses", new { page = page - }) : "";
var nextLink = page < totalPages - ? urlHelper.Link("Courses", new { page = page + }) : ""; var results = query
.Skip(pageSize * page)
.Take(pageSize)
.ToList()
.Select(s => TheModelFactory.Create(s)); return new
{
TotalCount = totalCount,
TotalPages = totalPages,
PrevPageLink = prevLink,
NextPageLink = nextLink,
Results = results
}; }
解释一下上面的代码:
在Get方法上添加了2个有默认值的参数,这两个参数就是用来过滤我们查询结果集的——例如:我们想获取第2页的数据,那么对应的Get请求就应该是这种形式:http://localhost:{your_port}/api/courses/?page=1,注意:在这里我们只给了一个参数,那么pageSize就是默认值10.
客户端收到的部分响应就应该是:
{
"totalCount": 32,
"totalPages": 4,
"prevPageLink": "http://localhost:3300/api/courses?page=0&pageSize=10",
"nextPageLink": "http://localhost:3300/api/courses?page=2&pageSize=10",
"results": [
{
"id": 11,
"url": "http://localhost:3300/api/courses/11",
"name": "English Education 2",
"duration": 4,
"description": "The course will talk in depth about: English Education 2",
"tutor": {
"id": 4,
"email": "Kareem.Ismail@outlook.com",
"userName": "KareemIsmail",
"firstName": "Kareem",
"lastName": "Ismail",
"gender": 0
},
"subject": {
"id": 4,
"name": "English"
}
},
Repository中GetAllCourses的返回值为IQueryable,因此在执行skip和take方法时并没有到SQL Server中执行SQL语句,最后查询的也是分页好的数据,体现出按需查询的特色。
在我们返回给客户端的数据中,其中分页元数据中包含了totalCount, totalPages, prevPageLink, nextPageLink这些数据,对于客户端来说我们返回totalCount, totalPages这两条数据非常有用,这样就可以与一些Grid配合使用来绑定结果。
通常来说我们会将分页元数据封装在响应Body中,对于开发者来说我们提供了所有分页信息。但有的API消费者因此只想获取它请求的数据而不需要分页元数据,那么他在解析响应结果是就会很费劲,因此这里出现了另一种方式来向客户端响应分页元数据——在响应报文头部附加分页元数据:Body部分只包含请求的资源,我们新增一个头部信息“X-Pagination”。
Way2.封装分页元数据到响应Header中
我们修改StudentsController来实现将分页元数据封装在Header中,使用这种方法后,需要分页元数据的客户端直接从Header部分获取,不需要的客户端直接解析响应的Body即可。
实现起来也非常简单,下面上代码:
public IEnumerable<StudentBaseModel> Get(int page = , int pageSize = )
{
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 > ? urlHelper.Link("Students", new { page = page - , pageSize = pageSize }) : "";
var nextLink = page < totalPages - ? urlHelper.Link("Students", new { page = page + , 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;
}
这里我们添加了一个Header,里面包含一个Json序列化的分页元数据,客户端收到的响应:

总结
2种分页技术各有优劣,感觉碰到具体应用的时候再做选择了。下一章将介绍Web Api安全性,实现Basic authentication
说明:对于项目的代码,由于之前学习了一点Git,所以从这一章起,我已经托管在github上了,以后最新的代码就直接在github上更新
源码地址:https://github.com/fzrain/WebApi.eLearning
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【七】——实现资源的分页的更多相关文章
- ASP.NET Web Api构建基于REST风格的服务实战系列教程
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程[十]——使用CacheCow和ETag缓存资源 系列导航地址http://www.cnblogs.com/fzrain/p/3 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【开篇】【持续更新中。。。】
最近发现web api很火,园内也有各种大神已经在研究,本人在asp.net官网上看到一个系列教程,原文地址:http://bitoftech.net/2013/11/25/detailed-tuto ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【九】——API变了,客户端怎么办?
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 一旦我们将API发布之后,消费者就会开始使用并和其他的一些数据混在一起.然而,当新的需求出现 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这一篇文章我们主要来探讨一下Web Api的安全性,到目前为止所有的请求都是走的Http协议 ...
- [转]使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【八】——Web Api的安全性
本文转自:http://www.cnblogs.com/fzrain/p/3552423.html 系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html ...
- 使用ASP.NET WEB API构建基于REST风格的服务实战系列教程(一)——使用EF6构建数据库及模型
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 使用Entity Framework Code First模式构建数据库对象 已经决定使用EF C ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【二】——使用Repository模式构建数据库访问层
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在数据访问层应用Repository模式来隔离对领域对象的细节操作是很有意义的.它位于映射层 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【五】——在Web Api中实现Http方法(Put,Post,Delete)
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 在Web Api中,我们对资源的CRUD操作都是通过相应的Http方法来实现——Post(新 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【外传】——Attribute Routing
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 题外话:由于这个技术点是新学的,并不属于原系列,但借助了原系列的项目背景,故命名外传系列,以后也可 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【三】——Web Api入门
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 经过前2节的介绍,我们已经把数据访问层搭建好了,从本章开始就是Web Api部分了.在正式开 ...
随机推荐
- 51nod 1013快速幂 + 费马小定理
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1013 这是一个等比数列,所以先用求和公式,然后和3^(n+1)有关,有n ...
- C#-WinForm-打开其他窗体的三种方式-Show()、设置Owner()、ShowDialog()
打开其他窗体的三种方式 Show - 例如登入界面进入主页面,直接将主页面展示出来,两个窗体互不影响 public partial class Form1 : Form { public Form1( ...
- iOS 硬件授权检测:定位服务、通讯录、日历、提醒事项、照片、蓝牙共享、麦克风、相机等(转)
转载自:http://www.cocoachina.com/ios/20151214/14502.html iOS系统版本的不断升级的前提,伴随着用户使用设备的安全性提升,iOS系统对于App需要使用 ...
- R语言快速入门上手
导言: 较早之前就听说R是一门便捷的数据分析工具,但由于课程设计的原因,一直没有空出足够时间来进行学习.最近自从决定本科毕业出来找工作之后,渐渐开始接触大数据行业的技术,现在觉得是时候把R拿下 ...
- 58. Android一些开发习惯总结
作者:漫步 链接:https://www.zhihu.com/question/27227425/answer/35973793 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- 【SDOI2010题集整合】BZOJ1922~1927&1941&1951&1952&1972&1974&1975
BZOJ1922大陆争霸 思路:带限制的单源最短路 限制每个点的条件有二,路程和最早能进入的时间,那么对两个值一起限制跑最短路,显然想要访问一个点最少满足max(dis,time) 那么每次把相连的点 ...
- 【BZOJ-2453&2120】维护队列&数颜色 分块 + 带修莫队算法
2453: 维护队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 653 Solved: 283[Submit][Status][Discuss] ...
- Slave2: no datanode to stop(HADOOP_PID_DIR)
HADOOP_PID_DIR 本想在环境变量里设置,在相关文件里直接尹用,但是我想起来那时候的JAVA_HOME都不行,还是一个一个设置吧. 有时候,我们对运行几天或者几个月的hadoop或者hbas ...
- BZOJ3295 [Cqoi2011]动态逆序对
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- Linux C/C++ Memory Leak Detection Tool
目录 . 内存使用情况分析 . 内存泄漏(memory leak) . Valgrind使用 1. 内存使用情况分析 0x1: 系统总内存的分析 可以从proc目录下的meminfo文件了解到当前系统 ...