web api封装分页

原创 2016年08月28日 15:02:31


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

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

public Object Get(int page = 0, int pageSize = 10)
     {
         IQueryable<model> 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("<pre name="code" class="csharp" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 30px; text-indent: 28px;">model
", new { page = page - 1 }) : ""; var nextLink = page < totalPages - 1 ? urlHelper.Link("model", 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”。

2.封装分页元数据到响应Header中

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;
        }

总结

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




Dynamics CRM2016 Web Api之分页查询

在dynamics crm web api还没出现前,我们是通过fetchxml来实现的,当然这种方式依旧可行,那既然web api来了我们就拥抱新的方式。    web api中我们通过指定查询的条...
  • woniu1104913
  • woniu1104913
  • 2016年12月01日 22:37
  • 1035

Contact Manager Web API 分页和查询(Paging and Querying)

Contact Manager Web API  分页和查询(Paging and Querying) 联系人管理器web API是一个Asp.net web api示例程序,演示了...
  • huwei2003
  • huwei2003
  • 2015年08月04日 18:24
  • 1210

Java数据分页通用封装

数据库分页, 从客户角度来看,主要是提供两个参数:每页数量(pageSize),当前页(currentPage)。 从后台处理来看,主要是分页查询数据库,查询总数;   我这里的封装参考eas...
  • wutbiao
  • wutbiao
  • 2012年08月30日 11:38
  • 10929

自己封装的简单Jquery分页插件

//封装分页方法 var currentPage = '${page.currentPage}';//获得当前页 var totalPage = '${page.totalPage}';/...
  • u010859137
  • u010859137
  • 2015年01月16日 09:30
  • 414

openstack api详细介绍

unitedstack 一些参考文档,从中找到一些从API/数据库/单元测试入手的文档,整理如下: http://www.infoq.com/cn/articles/OpenStack-Unit...
  • hexiaodouaipiqiu
  • hexiaodouaipiqiu
  • 2016年07月27日 19:09
  • 196

jpa+spring对实体的crud和实现分页功能的简单实用的封装

 分页类的封装:============================================================================================...
  • drawtakes
  • drawtakes
  • 2009年11月07日 21:59
  • 1109

Vue封装分页组件

原文地址:http://www.cnblogs.com/jh007/p/6185599.html css样式文件 pagination.css ul, li { margin: 0...
  • tanga842428
  • tanga842428
  • 2017年06月13日 13:00
  • 560

PHP,分页函数封装成类

最近因为项目用到php。查看文档,基本看懂怎么用,怎么说呢,很多特性或者习惯,习惯了python,就觉得php很多不可理喻之处。当然,可能我对于php的造化尚浅吧。 写了一个分页函数,然后封装成类,...
  • rsj217
  • rsj217
  • 2012年08月25日 21:57
  • 2408

简单的分页封装(一)

分页对象接口: public interface Paginable { /** * 总记录数 * * @return */ public int getTotalCount(...
  • qq_19244423
  • qq_19244423
  • 2015年06月03日 16:25
  • 1109

Web API接口设计经验总结

Web API接口设计经验总结 在Web API接口的开发过程中,我们可能会碰到各种各样的问题,我在前面两篇随笔《Web API应用架构在Winform混合框架中的应用(1)》、《Web ...
  • rise51
  • rise51
  • 2016年06月04日 18:26
  • 5623
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:web api封装分页
举报原因:
原因补充:

(最多只允许输入30个字)