ASP.NET Web Api 实现数据的分页
前言
這篇文章我們將使用不同的方式實(shí)現(xiàn)手動(dòng)分頁(yè)(關(guān)于高端大氣上檔次的OData本文暫不涉及,但有可能會(huì)在系列的后期介紹,還沒(méi)確定。。。),對(duì)于分頁(yè)的結(jié)果,我們將采用2種不同的方式響應(yīng)給客戶端(1.將分頁(yè)元數(shù)據(jù)封裝在響應(yīng)Body中2.在http響應(yīng)報(bào)文頭部添加分頁(yè)信息)。
眾所周知,在服務(wù)器端一次性返回成百上千條數(shù)據(jù)是非??植赖?#xff0c;在我們?cè)O(shè)計(jì)Api的時(shí)候,對(duì)于Get方法我們應(yīng)該以分頁(yè)的方式返回。例如:每次響應(yīng)給客戶端10條數(shù)據(jù),并且包含“上一頁(yè)”和“下一頁(yè)”的標(biāo)簽,這樣用戶就能去獲得他想要的數(shù)據(jù)。
Way1.封裝分頁(yè)元數(shù)據(jù)封裝在響應(yīng)Body中
修改“CoursesController”的Get方法實(shí)現(xiàn)分頁(yè)而不是一次性把所有數(shù)據(jù)返回,下面上代碼:
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個(gè)有默認(rèn)值的參數(shù),這兩個(gè)參數(shù)就是用來(lái)過(guò)濾我們查詢結(jié)果集的——例如:我們想獲取第2頁(yè)的數(shù)據(jù),那么對(duì)應(yīng)的Get請(qǐng)求就應(yīng)該是這種形式:http://localhost:{your_port}/api/courses/?page=1,注意:在這里我們只給了一個(gè)參數(shù),那么pageSize就是默認(rèn)值10.
客戶端收到的部分響應(yīng)就應(yīng)該是:
{"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,因此在執(zhí)行skip和take方法時(shí)并沒(méi)有到SQL Server中執(zhí)行SQL語(yǔ)句,最后查詢的也是分頁(yè)好的數(shù)據(jù),體現(xiàn)出按需查詢的特色。
在我們返回給客戶端的數(shù)據(jù)中,其中分頁(yè)元數(shù)據(jù)中包含了totalCount, totalPages, prevPageLink, nextPageLink這些數(shù)據(jù),對(duì)于客戶端來(lái)說(shuō)我們返回totalCount, totalPages這兩條數(shù)據(jù)非常有用,這樣就可以與一些Grid配合使用來(lái)綁定結(jié)果。
通常來(lái)說(shuō)我們會(huì)將分頁(yè)元數(shù)據(jù)封裝在響應(yīng)Body中,對(duì)于開(kāi)發(fā)者來(lái)說(shuō)我們提供了所有分頁(yè)信息。但有的API消費(fèi)者因此只想獲取它請(qǐng)求的數(shù)據(jù)而不需要分頁(yè)元數(shù)據(jù),那么他在解析響應(yīng)結(jié)果是就會(huì)很費(fèi)勁,因此這里出現(xiàn)了另一種方式來(lái)向客戶端響應(yīng)分頁(yè)元數(shù)據(jù)——在響應(yīng)報(bào)文頭部附加分頁(yè)元數(shù)據(jù):Body部分只包含請(qǐng)求的資源,我們新增一個(gè)頭部信息“X-Pagination”。
Way2.封裝分頁(yè)元數(shù)據(jù)到響應(yīng)Header中
我們修改StudentsController來(lái)實(shí)現(xiàn)將分頁(yè)元數(shù)據(jù)封裝在Header中,使用這種方法后,需要分頁(yè)元數(shù)據(jù)的客戶端直接從Header部分獲取,不需要的客戶端直接解析響應(yīng)的Body即可。
實(shí)現(xiàn)起來(lái)也非常簡(jiǎn)單,下面上代碼:
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;}這里我們添加了一個(gè)Header,里面包含一個(gè)Json序列化的分頁(yè)元數(shù)據(jù),客戶端收到的響應(yīng):
總結(jié)
2種分頁(yè)技術(shù)各有優(yōu)劣,感覺(jué)碰到具體應(yīng)用的時(shí)候再做選擇了
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Web Api 实现数据的分页的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 益阳开车到承德董存瑞烈士陵园距离有多远
- 下一篇: XStream转换Java对象与XML