前言

这篇文章我们将使用不同的方式实现手动分页(关于高端大气上档次的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. jmter提交图片

    jmter提交图片 https://www.cnblogs.com/linglingyuese/p/4514808.html

  2. No.18 selenium学习之路之批量执行测试用例

    diascover方法,加载所有测试用例 1.discover方法里面有三个参数: -case_dir:测试用例的目录 -pattern:这个是匹配脚本名称的规则,test*.py意思是匹配test开 ...

  3. Codeforces 580D Kefa and Dishes(状态压缩DP)

    题目链接:http://codeforces.com/problemset/problem/580/D 题目大意:有n盘菜每个菜都有一个满意度,k个规则,每个规则由x y c组成,表示如果再y之前吃x ...

  4. (三)Jsoup 使用选择器语法查找 DOM 元素

    第一节: Jsoup 使用选择器语法查找 DOM 元素 Jsoup使用选择器语法查找DOM元素 我们前面通过标签名,Id,Class样式等来搜索DOM,这些是不能满足实际开发需求的, 很多时候我们需要 ...

  5. set IDENTITY_INSERT on 和 off 的设置

    qlserver 批量插入记录时,对有标识列的字段要设置 set IDENTITY_INSERT 表名 on,然后再执行插入记录操作;插入完毕后恢复为 off 设置 格式:  set IDENTITY ...

  6. 如何验证一个地址可否使用—— MmIsAddressValid函数分析

    又是一篇内核函数分析的博文,我个人觉得Windows的内核是最好的老师,当你想实现一个功能之前可以看看Windows内核是怎么做的,说不定就有灵感呢:) 首先看下官方的注释说明: /*++ Routi ...

  7. appium+python 【Mac】Android夜神模拟器

    1.官网下载地址:https://www.yeshen.com/ 2.具体的夜神模拟器的介绍请自查 3.下载安装后夜神模拟器后,打开模拟器,进行相应的配置如下: 4. (1).找到android-sd ...

  8. Yii2之控制台命令篇(console)

    控制台命令 Yii 中有一个拥有丰富功能的控制台,它们主要用于创建网站后台处理的任务.在项目根目录下执行相关操作,有意思的事,可以通过 yii 自带的功能,列出当前已有的命令. 1.查看当前项目控制台 ...

  9. 《Android源码设计模式》--单例模式

    No1: 懒汉单例模式优缺点分析 public class Singleton{ private static Singleton instance; private Singleton(){} pu ...

  10. 模拟界面请求到web服务器

    客户端 package com.lsw.client; import java.io.*; import java.net.*; import java.util.*; public class HT ...