.NET PAGE分页

一、功能说明

  1. 当前端传入分页查询信息时,会校验并修改请求分页的信息
ini 复制代码
    public class RequestPage
    {

        public string? keyword { get; set; }

        private const int maxSize = 20;

        private int _pageNumber = 1;
        public int pageNumber
        {
            get => _pageNumber;
            set => _pageNumber = value < 1 ? 1 : value;   
        }
        private int _pageSize = 10 ; 
        public int pageSize
        {
            get => _pageSize;
            set => _pageSize = value < 1 ? 10 : ((value > maxSize) ? maxSize : value);
        }
    }

新建了一个类接受分页参数,实现了如下功能:

  • 默认每页最大展示20条,并且当没有参数传入时,默认展示第1页的前10条数据

  • 当传入的分页信息为负数时,展示第1页的前10条数据


  1. 默认会查询符合条件的所有信息,并且针对前端传递的pageSize和pageNumber截取并返回数据
csharp 复制代码
    public class ResponsePage<T>:List<T>
    {
        public int currentPage { get; private set; }
        public int totalPages { get; private set; }

        public int pageSize { get; private set; }

        public int totalCount { get; private set; }

        public bool hasPrevious => currentPage > 1;

        public bool hasNext => currentPage < totalPages;

        public ResponsePage(List<T> items,int count,int pageNumber,int pageSize)
        {
            totalCount = count;
            pageSize = pageSize;
            currentPage = pageNumber;
            totalPages = (int)Math.Ceiling(count / (double)pageSize);
            AddRange(items);
        }

        public static ResponsePage<T> Create(IQueryable<T> source,int pageNumber,int pageSize)
        {
            var count = source.Count();
            var items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
            return new ResponsePage<T>(items, count, pageNumber, pageSize);
        }
    }

使用演示:

ini 复制代码
        [HttpGet(Name = nameof(GetUserInfo))]
        public object GetUserInfo([FromQuery]RequestPage? page)
        {

            // 初始化Bogus库
            var faker = new Faker();

            // 生成100个随机用户
            var users = Enumerable.Range(1, 100).Select(i =>
                new User
                {
                    Name = faker.Name.FullName(),
                    Age = faker.Random.Int(18, 60),
                    Email = faker.Internet.Email()
                });

            // 将用户列表转换为IQueryable对象
            var queryableUsers = users.AsQueryable();

            ResponsePage<User> res = ResponsePage<User>.Create(queryableUsers, page.pageNumber, page.pageSize);

            return res;
        }

  1. 请求头会捎带上一页下一页的请求地址以及分页信息
ini 复制代码
 ResponsePage<User> res = ResponsePage<User>.Create(queryableUsers, page.pageNumber, page.pageSize);

var previousLink = res.hasPrevious
    ? CreateResourceUri(page, ResourceUriType.PreviousPage)
    : null;

var nextLink = res.hasNext
   ? CreateResourceUri(page, ResourceUriType.NextPage)
   : null;

var paginationMetadata = new
{
    totalCount = res.totalCount,
    pageSize = res.pageSize,
    currentPage = res.currentPage,
    totalPages = res.totalPages,
    previousLink,
    nextLink
};
ini 复制代码
   private string CreateResourceUri(RequestPage page, ResourceUriType type)
        {
            switch (type)
            {
                case ResourceUriType.PreviousPage:
                    return Url.Link(nameof(GetUserInfo), new
                    {
                        pageNumber = page.pageNumber - 1,
                        pageSize = page.pageSize,
                        keyword = page.keyword
                    });
                case ResourceUriType.NextPage:
                    return Url.Link(nameof(GetUserInfo), new
                    {
                        pageNumber = page.pageNumber + 1,
                        pageSize = page.pageSize,
                        keyword = page.keyword
                    });
                default:
                    return Url.Link(nameof(GetUserInfo), new
                    {
                        pageNumber = page.pageNumber + 1,
                        pageSize = page.pageSize,
                        keyword = page.keyword
                    });
            }
        }

请求第一页的前3条数据,因为这是第一页,所以没有上一页,返回Null;而下一页信息,只是在这次请求的基础修改了pageNumber + 1

二、核心代码

ini 复制代码
using Bogus;
using MassTransit.Futures.Contracts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Routing;
using System.Security.AccessControl;
using  page_1.Controllers;
using System.Text.Encodings.Web;
using System.Text.Json;

namespace page_1.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {

        [HttpGet(Name = nameof(GetUserInfo))]
        public object GetUserInfo([FromQuery]RequestPage? page)
        {

            // 初始化Bogus库
            var faker = new Faker();

            // 生成100个随机用户
            var users = Enumerable.Range(1, 100).Select(i =>
                new User
                {
                    Name = faker.Name.FullName(),
                    Age = faker.Random.Int(18, 60),
                    Email = faker.Internet.Email()
                });

            // 将用户列表转换为IQueryable对象
            var queryableUsers = users.AsQueryable();

            ResponsePage<User> res = ResponsePage<User>.Create(queryableUsers, page.pageNumber, page.pageSize);

            var previousLink = res.hasPrevious
                ? CreateResourceUri(page, ResourceUriType.PreviousPage)
                : null;

            var nextLink = res.hasNext
               ? CreateResourceUri(page, ResourceUriType.NextPage)
               : null;

            var paginationMetadata = new
            {
                totalCount = res.totalCount,
                pageSize = res.pageSize,
                currentPage = res.currentPage,
                totalPages = res.totalPages,
                previousLink,
                nextLink
            };


            Response.Headers.Add("X-Pagination", JsonSerializer.Serialize(paginationMetadata,
                new JsonSerializerOptions
                {
                    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
                }));

            return res;
        }


        private string CreateResourceUri(RequestPage page, ResourceUriType type)
        {
            switch (type)
            {
                case ResourceUriType.PreviousPage:
                    return Url.Link(nameof(GetUserInfo), new
                    {
                        pageNumber = page.pageNumber - 1,
                        pageSize = page.pageSize,
                        keyword = page.keyword
                    });
                case ResourceUriType.NextPage:
                    return Url.Link(nameof(GetUserInfo), new
                    {
                        pageNumber = page.pageNumber + 1,
                        pageSize = page.pageSize,
                        keyword = page.keyword
                    });
                default:
                    return Url.Link(nameof(GetUserInfo), new
                    {
                        pageNumber = page.pageNumber + 1,
                        pageSize = page.pageSize,
                        keyword = page.keyword
                    });
            }
        }
    }


    public enum ResourceUriType
    {
        PreviousPage, NextPage
    }


    // 定义一个用户类
    public class User
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Email { get; set; }
    }



    public class RequestPage
    {

        public string? keyword { get; set; }

        private const int maxSize = 20;

        private int _pageNumber = 1;
        public int pageNumber
        {
            get => _pageNumber;
            set => _pageNumber = value < 1 ? 1 : value;   
        }
        private int _pageSize = 10 ; 
        public int pageSize
        {
            get => _pageSize;
            set => _pageSize = value < 1 ? 10 : ((value > maxSize) ? maxSize : value);
        }
    }

    public class ResponsePage<T>:List<T>
    {
        public int currentPage { get; private set; }
        public int totalPages { get; private set; }

        public int pageSize { get; private set; }

        public int totalCount { get; private set; }

        public bool hasPrevious => currentPage > 1;

        public bool hasNext => currentPage < totalPages;

        public ResponsePage(List<T> items,int count,int pageNumber,int pageSize)
        {
            totalCount = count;
            pageSize = pageSize;
            currentPage = pageNumber;
            totalPages = (int)Math.Ceiling(count / (double)pageSize);
            AddRange(items);
        }

        public static ResponsePage<T> Create(IQueryable<T> source,int pageNumber,int pageSize)
        {
            var count = source.Count();
            var items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();
            return new ResponsePage<T>(items, count, pageNumber, pageSize);
        }
    }

}
相关推荐
计算机毕设指导617 分钟前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven
计算机-秋大田25 分钟前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
羊小猪~~2 小时前
MYSQL学习笔记(九):MYSQL表的“增删改查”
数据库·笔记·后端·sql·学习·mysql·考研
豌豆花下猫2 小时前
Python 潮流周刊#90:uv 一周岁了,优缺点分析(摘要)
后端·python·ai
橘猫云计算机设计3 小时前
基于SSM的《计算机网络》题库管理系统(源码+lw+部署文档+讲解),源码可白嫖!
java·数据库·spring boot·后端·python·计算机网络·毕设
熬夜苦读学习3 小时前
Linux文件系统
linux·运维·服务器·开发语言·后端
坚定信念,勇往无前4 小时前
Spring Boot 如何保证接口安全
spring boot·后端·安全
程序员侠客行5 小时前
Spring事务原理详解 三
java·后端·spring·架构
Hello.Reader6 小时前
深入理解 Rust 的 `Rc<T>`:实现多所有权的智能指针
开发语言·后端·rust
yoona10206 小时前
Rust编程语言入门教程(八)所有权 Stack vs Heap
开发语言·后端·rust·区块链·学习方法