前言

这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可能会在系列的后期介绍,还没确定。。。),对于分页的结果,我们将采用2种不同的方式响应给客户端(1.将分页元数据封装在响应Body中2.在http响应报文头部添加分页信息)。

众所周知,在服务器端一次性返回成百上千条数据是非常恐怖的,在我们设计Api的时候,对于Get方法我们应该以分页的方式返回。例如:每次响应给客户端10条数据,并且包含“上一页”和“下一页”的标签,这样用户就能去获得他想要的数据。

Way1.封装分页元数据封装在响应Body中

修改“CoursesController”的Get方法实现分页而不是一次性把所有数据返回,下面上代码:

public Object Get(int page = 0, int pageSize = 10)
{
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 > 0 ? urlHelper.Link("Courses", new { page = page - 1 }) : "";
var nextLink = page < totalPages - 1 ? urlHelper.Link("Courses", new { page = page + 1 }) : ""; 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 = 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;
}

这里我们添加了一个Header,里面包含一个Json序列化的分页元数据,客户端收到的响应:

总结

2种分页技术各有优劣,感觉碰到具体应用的时候再做选择了

ASP.NET Web Api 实现数据的分页的更多相关文章

  1. ASP.NET Web Api 实现数据的分页(转载)

    转载地址:http://www.cnblogs.com/fzrain/p/3542608.html 前言 这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的OData本文暂不涉及,但有可能 ...

  2. MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

    ASP.NET Web API和WCF都体现了REST软件架构风格.在REST中,把一切数据视为资源,所以也是一种面向资源的架构风格.所有的资源都可以通过URI来唯一标识,通过对资源的HTTP操作(G ...

  3. 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理

    在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...

  4. ASP.NET Web API中把分页信息放Header中返回给前端

    谈到ASP.NET Web API的分页,考虑的因素包括: 1.上一页和下一页的uri2.总数和总页数3.当前页和页容量 接着是服务端的数据以怎样的形式返回? 我们通常这样写: {    totalC ...

  5. 前端使用AngularJS的$resource,后端ASP.NET Web API,实现分页、过滤

    在上一篇中实现了增删改查,本篇实现分页和过滤. 本系列包括: 1.前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查2.前端使用AngularJS的$re ...

  6. 能省则省:在ASP.NET Web API中通过HTTP Headers返回数据

    对于一些返回数据非常简单的 Web API,比如我们今天遇到的“返回指定用户的未读站内短消息数”,返回数据就是一个数字,如果通过 http response body 返回数据,显得有些奢侈.何不直接 ...

  7. 【ASP.NET Web API教程】5.3 发送HTML表单数据:文件上传与多部分MIME

    原文:[ASP.NET Web API教程]5.3 发送HTML表单数据:文件上传与多部分MIME 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面 ...

  8. 【ASP.NET Web API教程】5.2 发送HTML表单数据:URL编码的表单数据

    原文:[ASP.NET Web API教程]5.2 发送HTML表单数据:URL编码的表单数据 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  9. ASP.NET Web API实践系列07,获取数据, 使用Ninject实现依赖倒置,使用Knockout实现页面元素和视图模型的双向绑定

    本篇接着上一篇"ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API",尝试获取数据. 在Models文件夹下创 ...

随机推荐

  1. Java线程的阻塞

    线程的阻塞 线程的优先级 线程总是存在优先级,优先级范围在1~10之间,线程默认优先级是5(数值越大优先级越高): JVM线程调度程序是基于优先级的抢先调度机制: 在大多数情况下,当前运行的线程优先级 ...

  2. 【笔记】jQuery插件开发指南

    原文链接:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html (有部分增删和修改) jQuery插件开发模式 软件开发过程中是需要一定 ...

  3. 泛型 for to/in 遍历 PK 效率;TEnumerator、TEnumerable

    再使用泛型的时候,经常需要用到遍历功能: 只要继承了 TEnumerator 或 TEnumerable 这两个抽象类的 都具有遍历功能. 当然没有继承这两个抽象类的 也具有使用 for in 来遍历 ...

  4. Linux同步互斥(Peterson算法,生产者消费者模型)

    同步 两个或两个以上随时间变化的量在变化过程中保持一定的相对关系. 互斥 对一组并发进程,一次只有一个进程能够访问一个给定的资源或执行一个给定的功能. 互斥技术可以用于解决诸如资源争用之类的冲突,还可 ...

  5. 洛谷 P1992 不想兜圈的老爷爷 题解

    洛谷 P1992 不想兜圈的老爷爷 题解 题目描述 一位年过古稀的老爷爷在乡间行走 而他不想兜圈子 因为那会使他昏沉 偶然路过小A发扬助人为乐优良传统 带上地图 想知道路况是否一定使他清醒 usqwe ...

  6. 使用apt install和使用apt-get install的区别是什么

    apt-get是老版的命令,apt是新版的命令,apt还包含了apt-get cache等等,用起来更方便.因为apt刚刚出来,所以允许有apt-get和apt共存,以后apt-get就要淘汰了.

  7. 推荐 远程部署 fabric

    自己写的一个例子: from fabric.api import run, env env.hosts = ['nanjing','hefei','haerbin','lanzhou','taiyua ...

  8. require demo 记录备份

    预览地址 http://127.0.0.1:8020/requireDemo/myNEW/index.html 注意 远程的 非模块的 empty: demo2

  9. Caffe训练AlexNet网络模型——问题一

    训练AlexNet网络时,出现Check failed:datum_height >= crop_size (size vs. 227)错误,具体如下图所示: 根据提示,问题是crop_size ...

  10. 001 Anaconda的介绍与安装

    1.官网 www.continuum.io 2.ananconda的版本 同一个版本下对应一个python3与python2,在这里下载使用python 2.7的版本. 3.概述 Anaconda是一 ...