/// <summary> /// 为集合资源添加HATEOAS的LINKS /// </summary> /// <param name="postResourceParameters"></param> /// <param name="hasPrevious">是否具有前一页属性</param> /// <param name="hasNext">是否具有后一页属性</param> /// <returns>LinkResource集合</returns> private IEnumerable <LinkResource> CreateLinksForPosts(PostQueryParameters postResourceParameters, bool hasPrevious, bool hasNext) { var links = new List <LinkResource> { new LinkResource( CreatePostUri(postResourceParameters, PaginationResourceUriType.CurrentPage, "getPosts"), "self", "GET") }; if (hasPrevious) { links.Add( new LinkResource( CreatePostUri(postResourceParameters, PaginationResourceUriType.PreviousPage, "getPosts"), "previous_page", "GET")); } if (hasNext) { links.Add( new LinkResource( CreatePostUri(postResourceParameters, PaginationResourceUriType.NextPage, "getPosts"), "next_page", "GET")); } return(links); }
/// <summary> /// 生成前一页,后一页,当前页的URI链接方法 /// </summary> /// <param name="parameters">页面的元数据</param> /// <param name="uriType">URI类型</param> /// <param name="actionName">需要调用的ActionName</param> /// <returns></returns> private string CreatePostUri(PostQueryParameters parameters, PaginationResourceUriType uriType, string actionName) { switch (uriType) { case PaginationResourceUriType.PreviousPage: var previousParameters = new { pageIndex = parameters.PageIndex - 1, pageSize = parameters.PageSize, orderBy = parameters.OrderBy, fields = parameters.Fields }; return(urlHelper.Link(actionName, previousParameters)); case PaginationResourceUriType.NextPage: var nextParameters = new { pageIndex = parameters.PageIndex + 1, pageSize = parameters.PageSize, orderBy = parameters.OrderBy, fields = parameters.Fields }; return(urlHelper.Link(actionName, nextParameters)); default: var currentParameters = new { pageIndex = parameters.PageIndex, pageSize = parameters.PageSize, orderBy = parameters.OrderBy, fields = parameters.Fields }; return(urlHelper.Link(actionName, currentParameters)); } }
public async Task <IActionResult> Get(PostQueryParameters postQueryParameters) { #region 参数合法性判断 //排序字段合法性判断 if (!string.IsNullOrWhiteSpace(postQueryParameters.OrderBy) && !propertyMappingContainer.ValidateMappingExistsFor <PostResource, Post>(postQueryParameters.OrderBy)) { return(BadRequest("排序属性映射关系不存在,或不可通过该排序属性排序")); } //塑形字段合法性判断 if (!string.IsNullOrWhiteSpace(postQueryParameters.Fields) && !typeHelperService.TypeHasProperties <PostResource>(postQueryParameters.Fields)) { return(BadRequest("传入的塑形属性不合法")); } #endregion //返回带有元数据的PaginatedList数据 var postsWithMateData = await postRepository.GetAllPostsAsync(postQueryParameters); //将posts集合映射为PostResource集合,取出其中的post数据集合 var postResources = mapper.Map <IEnumerable <Post>, IEnumerable <PostResource> >(postsWithMateData); //针对ResourceModel进行属性塑形 var shapedPostResources = postResources.ToDynamicIEnumerable(postQueryParameters.Fields); var previousPageLink = postsWithMateData.HasPrevious ? CreatePostUri(postQueryParameters, PaginationResourceUriType.PreviousPage, "GetPosts") : null; var nextPageLink = postsWithMateData.HasNext ? CreatePostUri(postQueryParameters, PaginationResourceUriType.NextPage, "GetPosts") : null; #region 提取元数据,并将该数据添加到响应Response自定义X-Pagination的Header中 //提取元数据 var mate = new { postsWithMateData.PageSize, postsWithMateData.PageIndex, postsWithMateData.TotalItemsCount, postsWithMateData.PageCount, previousPageLink, nextPageLink }; //将翻页元数据添加到响应Header的X-Pagination中 Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(mate, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() //将所有mate元数据属性首字母小写返回 })); #endregion //logger.LogError("测试的错误日志记录"); //throw new Exception("发生了错误"); return(Ok(shapedPostResources)); }
public async Task <PaginatedList <Post> > GetAllPostsAsync(PostQueryParameters postQueryParameters) { var query = myContext.Posts.AsQueryable(); #region 根据需求 过滤相关字段 if (!string.IsNullOrEmpty(postQueryParameters.Title)) { var title = postQueryParameters.Title.Trim().ToLowerInvariant(); //直接检索 //query = query.Where(x => x.Title.ToLowerInvariant() == title); //模糊查询 query = query.Where(x => x.Title.ToLowerInvariant().Contains(title)); //将pageindex设置为第一页起始,防止出现检索的数据不显示的问题 //需要考虑一下怎么解决 //postQueryParameters.PageIndex = 0; } #endregion //query = query.OrderBy(x => x.id); //传入参数,实现属性排序,传入需要排序ResourceModel的属性 query = query.ApplySort(postQueryParameters.OrderBy, propertyMappingContainer.Resolve <PostResource, Post>()); var count = await query.CountAsync(); var data = await query .Skip(postQueryParameters.PageIndex *postQueryParameters.PageSize) .Take(postQueryParameters.PageSize) .ToListAsync(); var paginatedList = new PaginatedList <Post>(postQueryParameters.PageIndex, postQueryParameters.PageSize, count, data); return(paginatedList); //return await myContext.Posts.ToListAsync(); }
public async Task <IActionResult> GetPostsHateoas(PostQueryParameters postQueryParameters) { #region 参数合法性判断 //排序字段合法性判断 if (!string.IsNullOrWhiteSpace(postQueryParameters.OrderBy) && !propertyMappingContainer.ValidateMappingExistsFor <PostResource, Post>(postQueryParameters.OrderBy)) { return(BadRequest("排序属性映射关系不存在,或不可通过该排序属性排序")); } //塑形字段合法性判断 if (!string.IsNullOrWhiteSpace(postQueryParameters.Fields) && !typeHelperService.TypeHasProperties <PostResource>(postQueryParameters.Fields)) { return(BadRequest("传入的塑形属性不合法")); } #endregion //返回带有元数据的PaginatedList数据 var postsWithMateData = await postRepository.GetAllPostsAsync(postQueryParameters); //将posts集合映射为PostResource集合,取出其中的post数据集合 var postResources = mapper.Map <IEnumerable <Post>, IEnumerable <PostResource> >(postsWithMateData); //针对ResourceModel进行属性塑形 var shapedPostResources = postResources.ToDynamicIEnumerable(postQueryParameters.Fields); #region 针对每个postResource添加HATEOAS的LINKS属性 var shapedWithLinks = shapedPostResources.Select(x => { var dict = x as IDictionary <string, object>; var postLinks = CreateLinksForPost((int)dict["id"], postQueryParameters.Fields); dict.Add("links", postLinks); return(dict); }); #endregion #region 针对整个postsResource添加HATEOAS的Links属性 var links = CreateLinksForPosts(postQueryParameters, postsWithMateData.HasPrevious, postsWithMateData.HasNext); var result = new { values = shapedWithLinks, links }; #endregion #region 提取元数据,并将该数据添加到响应Response自定义X-Pagination的Header中 //提取元数据 var mate = new { postsWithMateData.PageSize, postsWithMateData.PageIndex, postsWithMateData.TotalItemsCount, postsWithMateData.PageCount }; //将翻页元数据添加到响应Header的X-Pagination中 Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(mate, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() //将所有mate元数据属性首字母小写返回 })); #endregion //logger.LogError("测试的错误日志记录"); //throw new Exception("发生了错误"); return(Ok(result)); }