gpt4 book ai didi

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

转载 作者:我是一只小鸟 更新时间:2022-12-19 22:31:33 27 4
gpt4 key购买 nike

前言

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

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

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

通用请求参数

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

列表接口通用的参数是这几个: 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; }
}

                        
                      

文章列表请求参数

在通用请求参数 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 关键词覆盖基类属性,设置为默认排序是最后更新时间,前面加个减号表示倒序.

service

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

                        
                      

搜索的实现

在上面 service 的代码中 。

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

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

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

                        
                      

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

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

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

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

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

分页的实现

本项目使用 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; }
}

                        
                      

搞定 。

controller与最终效果

代码如下 。

                        
                          [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": [{...},{...},{...},{...},{...}]
}

                        
                      

系列文章

  • 基于.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) 文章列表接口分页、过滤、搜索、排序

最后此篇关于基于.NetCore开发博客项目StarBlog-(23)文章列表接口分页、过滤、搜索、排序的文章就讲到这里了,如果你想了解更多关于基于.NetCore开发博客项目StarBlog-(23)文章列表接口分页、过滤、搜索、排序的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com