基于.NetCore开发博客项目 StarBlog - (23) 文章列表接口分页、过滤、搜索、排序

1前言

上一篇留的坑,火速补上。

在之前的第6篇中,已经有初步介绍,本文做一些补充,已经搞定这部分的同学可以快速跳过,基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表

对标准的WebApi来说,分页、过滤、搜索、排序是很常见的功能,既可以方便用户查看数据,又可以提升程序性能。

2通用请求参数

定义一个类来作为通用的请求参数

列表接口通用的参数是这几个:PageSize, Page, Search, SortBy

反映到URL上,就是 Blog/?pageSize=10&page=1&search=关键词 这样的形式

public class QueryParameters {/// <summary>/// 最大页面条目/// </summary>public const int MaxPageSize = 50;private int _pageSize = 10;/// <summary>/// 页面大小/// </summary>public int PageSize {get => _pageSize;set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;}/// <summary>/// 当前页码/// </summary>public int Page { get; set; } = 1;/// <summary>/// 搜索关键词/// </summary>public string? Search { get; set; }/// <summary>/// 排序字段/// </summary>public string? SortBy { get; set; }
}

3文章列表请求参数

在通用请求参数 QueryParameters 的基础上,派生出文章列表的请求参数类 PostQueryParameters

public class PostQueryParameters : QueryParameters {/// <summary>/// 仅请求已发布文章/// </summary>public bool OnlyPublished { get; set; } = false;/// <summary>/// 文章状态/// </summary>public string? Status { get; set; }/// <summary>/// 分类ID/// </summary>public int CategoryId { get; set; } = 0;/// <summary>/// 排序字段/// </summary>public new string? SortBy { get; set; } = "-LastUpdateTime";
}

在通用请求参数的基础上,增加文章相关的筛选字段。

SortBy 字段使用 new 关键词覆盖基类属性,设置为默认排序是最后更新时间,前面加个减号表示倒序。

4service

StarBlog.Web/Services/PostService.cs 中封装获取分页列表的方法

代码里有注释,比较容易,根据 PostQueryParameters 中的各种参数来做过滤筛选

public IPagedList<Post> GetPagedList(PostQueryParameters param) {var querySet = _postRepo.Select;// 是否发布if (param.OnlyPublished) {querySet = _postRepo.Select.Where(a => a.IsPublish);}// 状态过滤if (!string.IsNullOrEmpty(param.Status)) {querySet = querySet.Where(a => a.Status == param.Status);}// 分类过滤if (param.CategoryId != 0) {querySet = querySet.Where(a => a.CategoryId == param.CategoryId);}// 关键词过滤if (!string.IsNullOrEmpty(param.Search)) {querySet = querySet.Where(a => a.Title.Contains(param.Search));}// 排序if (!string.IsNullOrEmpty(param.SortBy)) {// 是否升序var isAscending = !param.SortBy.StartsWith("-");var orderByProperty = param.SortBy.Trim('-');querySet = querySet.OrderByPropertyName(orderByProperty, isAscending);}return querySet.Include(a => a.Category).ToList().ToPagedList(param.Page, param.PageSize);
}

5搜索的实现

在上面 service 的代码中

可以看到搜索只是简单的“关键词过滤”

使用 Title.Contains(param.Search) ,转换成SQL就是

select * from post where title like '%关键词%'

单纯判断标题字符串中是否包含有关键词的子串。

这对于简单搜索一下文章是够用的,如果要像谷歌、百度这类搜索引擎一样能搜到文章的内容,需要用上全文检索。

现在主流的就是 ElasticSearch 和 Solr,后续可以考虑把这个功能加入本项目~

PS:关于全文检索,我之前写过一篇文章:全文检索引擎原理以及Lucene简单介绍

同时开源了一个玩具级的全文检索引擎,https://github.com/Deali-Axy/CloverSearch

6分页的实现

本项目使用 X.PagedList 来实现分页功能

这个组件在结合MVC使用很方便,如果纯WebApi的话,用数据库自带的分页是更好的选择,性能更好。

这个分页组件是在 IEnumerable<T> 上添加了扩展方法 ToPagedList,所以在用的时候要先把数据都读取出来,再执行分页,性能不如在数据库里做好分页再读出来,很多ORM都支持这个功能,FreeSQL也不例外。

用法例子:

var list = fsql.Select<Topic>().Where(a => a.Id > 10).Count(out var total) //总记录数量.Page(1, 20).Tolist();

详情请查看FreeSQL官方文档:https://freesql.net/guide/paging.html

用上 X.PagedList 这个组件后,在任意 IEnumerable<T> 对象上执行 ToPagedList 方法,可以得到 IPagedList<T> 对象

这个对象处理当前页面的列表数据,还有分页信息。

为了让前端可以方便的使用这部分信息,我又写了个扩展方法。

StarBlog.Web/Extensions/PagedListExt.cs

public static class PagedListExt {public static PaginationMetadata ToPaginationMetadata(this IPagedList page) {return new PaginationMetadata {PageCount = page.PageCount,TotalItemCount = page.TotalItemCount,PageNumber = page.PageNumber,PageSize = page.PageSize,HasNextPage = page.HasNextPage,HasPreviousPage = page.HasPreviousPage,IsFirstPage = page.IsFirstPage,IsLastPage = page.IsLastPage,FirstItemOnPage = page.FirstItemOnPage,LastItemOnPage = page.LastItemOnPage};}public static string ToPaginationMetadataJson(this IPagedList page) {return JsonSerializer.Serialize(ToPaginationMetadata(page));}
}

这样就可以在分页后得到的 IPagedList 对象上执行 ToPaginationMetadata 得到分页元数据了。

这个 PaginationMetadata 也是本项目里定义的 ViewModel,StarBlog.Web/ViewModels/PaginationMetadata.cs

代码如下

public class PaginationMetadata {public int PageCount { get; set; }public int TotalItemCount { get; set; }public int PageNumber { get; set; }public int PageSize { get; set; }public bool HasPreviousPage { get; set; }public bool HasNextPage { get; set; }public bool IsFirstPage { get; set; }public bool IsLastPage { get; set; }public int FirstItemOnPage { get; set; }public int LastItemOnPage { get; set; }
}

搞定

7controller与最终效果

代码如下

[AllowAnonymous]
[HttpGet]
public ApiResponsePaged<Post> GetList([FromQuery] PostQueryParameters param) {var pagedList = _postService.GetPagedList(param);return new ApiResponsePaged<Post> {Message = "Get posts list",Data = pagedList.ToList(),Pagination = pagedList.ToPaginationMetadata()};
}

获取到分页数据之后,输出 ApiResponsePaged<T> 类型的返回值

这个也是我封装的接口返回值类型,下一篇文章会详细介绍

Data 属性就是列表数据,Pagination 属性是分页的信息。

请求这个接口返回的效果如下

{"pagination": {"pageCount": 40,"totalItemCount": 394,"pageNumber": 1,"pageSize": 10,"hasPreviousPage": false,"hasNextPage": true,"isFirstPage": true,"isLastPage": false,"firstItemOnPage": 1,"lastItemOnPage": 10},"statusCode": 200,"successful": true,"message": "Get posts list","data": [{...},{...},{...},{...},{...}]
}

8系列文章

  • 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客?

  • 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目

  • 基于.NetCore开发博客项目 StarBlog - (3) 模型设计

  • 基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入

  • 基于.NetCore开发博客项目 StarBlog - (5) 开始搭建Web项目

  • 基于.NetCore开发博客项目 StarBlog - (6) 页面开发之博客文章列表

  • 基于.NetCore开发博客项目 StarBlog - (7) 页面开发之文章详情页面

  • 基于.NetCore开发博客项目 StarBlog - (8) 分类层级结构展示

  • 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入

  • 基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流

  • 基于.NetCore开发博客项目 StarBlog - (11) 实现访问统计

  • 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译

  • 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能

  • 基于.NetCore开发博客项目 StarBlog - (14) 实现主题切换功能

  • 基于.NetCore开发博客项目 StarBlog - (15) 生成随机尺寸图片

  • 基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)

  • 基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片

  • 基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传

  • 基于.NetCore开发博客项目 StarBlog - (19) Markdown渲染方案探索

  • 基于.NetCore开发博客项目 StarBlog - (20) 图片显示优化

  • 基于.NetCore开发博客项目 StarBlog - (21) 开始开发RESTFul接口

  • 基于.NetCore开发博客项目 StarBlog - (22) 开发博客文章相关接口

  • 基于.NetCore开发博客项目 StarBlog - (23) 文章列表接口分页、过滤、搜索、排序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在Chrome中保存您当前的所有标签,以便以后阅读

Chrome allows you to open tabs from your last browsing session when you open the browser. However, what if you want to save your current set of tabs to re-open at any time? Chrome doesn’t provide a way to do that natively, but there is an easy workaround…

ubuntu 16.04(Windows 10双系统+grub引导)无法进入tt1~tt6(NVIDIA驱动安装相关-黑屏,login loop,分辨率)...

目录 前言回顾最终解决&#xff1a;0.关闭x服务1.禁用nouveau2.加入3.更新4.查找匹配驱动5.选择推荐版本6.等待安装后重启,nvidia-smi查看是否安装成功,或者lsmod | grep nvidia&#xff0c;成功结果如下7.重启x服务8.此时还不能进入图形界面&#xff0c;因为nomodeset还在&…

(备忘)打开office2010总是在配置进度

1、同时按上键盘上面的windows键和R键&#xff0c;出现“运行” 2、输入“regedit”&#xff0c;回车进入注册表 3、点击“HKEY_CURRENT_USER”展开&#xff0c;依次“Software”--“Microsoft”--“Office”--"14.0"--"Word"展开&#xff0c;点击"Op…

java、oracle对CLOB处理

oracle CLOB字段转换位VARCHAR 1.实际上处理CLOB字段的时候&#xff0c;直接TO_CHAR&#xff0c;当长度超过4000的时候&#xff0c;会报错&#xff0c;提示列被截取&#xff1b; CLOB转varchar2&#xff1a;select to_char(CLOB字段) from table 2.直接使用SUBSTR对CLOB字段进行…

android 更改软键盘_如何在Android的Google键盘上更改声音和振动

android 更改软键盘Tactile feedback from a touch screen keyboard is crucial, in my opinion, but I don’t like sounds when I tap keys. You may not be like me—maybe sounds are your thing, but vibration is annoying. Or maybe you dislike both (you rebel!). The…

『 再看.NET7』看看required属性有什么不同

还是先看看C#中属性的这定义&#xff0c;在初始化和访问上有哪些方式&#xff0c;就能看出required属性有什么不一样的地方了。属性&#xff0c;是封装字段的&#xff0c;通过get和set访问器可以很好地验证数据的有效性。public record Order_00 {public Guid Id { get; set; }…

知识点:Mysql 索引原理完全手册(1)

知识点&#xff1a;Mysql 索引原理完全手册(1) 知识点&#xff1a;Mysql 索引原理完全手册(2) 知识点&#xff1a;Mysql 索引优化实战(3) 知识点&#xff1a;Mysql 数据库索引优化实战(4) Mysql-索引原理完全手册 一、 介绍二、 索引的原理三、 索引的数据结构四、 聚集索引与辅…

如何将Apple Mail建议用于事件和联系人

Apple products come preinstalled with an email client that can, on occasion, be quite smart. Today we want to show you another great feature: suggestions for event and contacts. Apple产品预装了一个电子邮件客户端&#xff0c;该客户端有时可能非常聪明。 今天&a…

TPshop表结构

tp_account_log -- 账户表 字段名字段类型默认值描述log_idmediumint(8) unsigned 日志iduser_idmediumint(8) unsigned 用户iduser_moneydecimal(10,2)0.00用户金额frozen_moneydecimal(10,2)0.00冻结金额pay_pointsmediumint(9) 支付积分change_timeint(10) unsigned 变动时间…

Redis 通配符批量删除key

问题&#xff1a; 线上有部分的redis key需要清理。 一、 由于Keys模糊匹配&#xff0c;请大家在实际运用的时候忽略掉。因为Keys会引发Redis锁&#xff0c;并且增加Redis的CPU占用&#xff0c;情况是很恶劣的&#xff0c; 官网说明如下&#xff1a; Warning: consider KEYS as…

如何在 .Net 7 中将 Query 绑定到数组

在 .Net 7 中&#xff0c;我们可以通过绑定数组的方式来接收来自查询字符串的参数。这样就不需要再使用逗号分隔的字符串来获取参数了。代码演示 假设我们需要从 query 上接受多个 id 并返回查询的结果。例如&#xff1a;id1&id2在 .Net 7 中&#xff0c;我们可以这样实现&…

xbox one 越狱_如何在Xbox One上播放视频和音乐文件

xbox one 越狱The Xbox One has integrated TV features and support for streaming media apps like Netflix and Hulu, but that isn’t where it ends. You can play video and music files you’ve ripped or downloaded by plugging in a USB drive or streaming them ove…

C++实验七

11——3 #include<fstream>using namespace std;int main(){ ofstream file; file.open("test1.txt",ios_base::binary); file<<"已成功添加字符&#xff01;"; file.close(); return 0; } 11-4 #include<fstream>#include<iostrea…

Visual Studio 15.4发布,新增多平台支持

微软发布了Visual Studio 2017的第四个升级版本&#xff0c;并且延续了支持.NET Standard 2.0和通用Windows平台&#xff08;UWP&#xff09;的承诺。.NET Standard 2.0支持是微软推动跨平台应用程序开发和代码重用战略的重要一环。\\15.4版本的变化与微软发布的预览版非常接近…

重新学习web后端开发-001-写在前面的话

"长风破浪会有时 直挂云帆济沧海" —— 李白<!-- more --> 1. 为什么会写这个系列 随着互联网技术飞速的非常&#xff0c;web开发一直都是互联网技术的重要部分之一。在作者十余年的工作中&#xff0c;经历了从程序员到高级工程师&#xff0c;然后开始负责项目…

WPF-20 ICommand命令绑定

这节我们介绍一下WPF中比较重要的接口ICommand&#xff0c;也是WPF中一个新的特性&#xff0c;做过WinForm朋友都知道&#xff0c;WinForm开发是基于事件驱动开发模式&#xff0c;比如一个Button有Click事件&#xff0c;当我点击该按钮时&#xff0c;在当前页面会执行具体的业务…

如何在Safari中查看网页的完整URL

Modern versions of Safari don’t show the entire URL of a page in the address bar—it just shows the web site’s domain name. If this bothers you, it’s easy to change. Safari的现代版本无法在地址栏中显示页面的整个URL&#xff0c;而仅显示网站的域名。 如果这困…

PHP | Uploading and reading of files and database 【PHP | 文件的上传和读取与数据库】

这是我自己的一个作业&#xff0c;用的是很基础的代码。 有错误的地方欢迎批评和指正&#xff01; 这里最容易出错的地方在读取数据后向数据库表中插入数据是的数据格式&#xff01; 文件上传的页面 uploading.php <html> <body align "center"> <fo…

Mqttnet内存与性能改进录

1 MQTTnet介绍MQTTnet是一个高性能的 .NET MQTT库&#xff0c;它提供MQTT客户端和MQTT服务器的功能&#xff0c;支持到最新MQTT5协议版本&#xff0c;支持.Net Framework4.5.2版本或以上。MQTTnet is a high performance .NET library for MQTT based communication. It provid…

DataArtisans战略联手阿里云 Apache Flink服务能力云化

近日&#xff0c;Apache Flink商业公司 CEO、联合创始人Kostas Tzoumas在云栖大会上宣布和阿里集团达成战略合作伙伴关系&#xff0c;希望能够借助全球最大的云计算公司之一阿里云&#xff0c;服务更多的大数据实时流计算的客户。同时期待通过加强和阿里集团技术合作&#xff0…