You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 2.0 REST API结合Angular服务端分页排序过滤咨询

实现.NET Core 2.0 REST API的服务端分页、排序与过滤

看起来你正在搭建和Angular前端交互的.NET Core 2.0 REST API,要搞定服务端分页、排序和过滤的功能对吧?先把你贴的API方法代码格式化一下,方便咱们后续分析:

[HttpGet]
public IActionResult Get(int activos=1, string source="", int idarticulo = -1, string filtro = "", string ordenar = "", int ordenarsentido = 1, int registroinic = -1, int registros = -1) 
{
    // 验证Token有效性
    if (!_validation.ValidarTo...
}

接下来,我会从参数整理、过滤、排序、分页这几个核心环节给你具体的实现建议,都是实际项目里常用的方案:

一、先把零散参数封装成强类型模型

你现在的方法参数太多了,后期维护起来容易晕,咱们把这些查询参数封装成一个实体类,不仅清晰,还方便加验证:

public class ArticleQueryParams
{
    public int Activos { get; set; } = 1;
    public string Source { get; set; } = string.Empty;
    public int IdArticulo { get; set; } = -1;
    public string Filtro { get; set; } = string.Empty;
    public string Ordenar { get; set; } = string.Empty;
    // 用枚举替代int,可读性拉满,避免传错值
    public SortDirection OrdenarSentido { get; set; } = SortDirection.Ascending;
    public int RegistroInic { get; set; } = -1;
    public int Registros { get; set; } = -1;
}

public enum SortDirection
{
    Ascending = 1,
    Descending = -1
}

然后修改你的API方法,用[FromQuery]绑定这个模型:

[HttpGet]
public IActionResult Get([FromQuery] ArticleQueryParams queryParams) 
{
    // 先把Token验证的逻辑补全,比如验证不通过返回Unauthorized
    if (!_validation.ValidarToken(HttpContext))
    {
        return Unauthorized();
    }
    // 后续的过滤、排序、分页逻辑都基于这个模型来做
}

二、过滤逻辑:逐步构建查询条件

假设你用EF Core操作数据库,咱们可以根据参数一步步缩小查询范围,避免写一堆if-else嵌套:

var query = _context.Articulos.AsQueryable();

// 过滤激活状态
query = query.Where(a => a.Activos == queryParams.Activos);

// 过滤来源,空字符串就跳过
if (!string.IsNullOrEmpty(queryParams.Source))
{
    query = query.Where(a => a.Source.Equals(queryParams.Source, StringComparison.OrdinalIgnoreCase));
}

// 过滤指定文章ID,默认-1就跳过
if (queryParams.IdArticulo != -1)
{
    query = query.Where(a => a.IdArticulo == queryParams.IdArticulo);
}

// 通用模糊搜索,比如搜标题、描述这些字段
if (!string.IsNullOrEmpty(queryParams.Filtro))
{
    query = query.Where(a => a.Titulo.Contains(queryParams.Filtro) 
                          || a.Descripcion.Contains(queryParams.Filtro));
    // 这里根据你的实际实体字段调整就行
}

三、排序逻辑:动态处理排序字段和方向

直接用字符串排序要注意字段名和实体属性一致,也可以用反射做更安全的动态排序,这里先给你最直观的实现:

if (!string.IsNullOrEmpty(queryParams.Ordenar))
{
    // 根据排序方向选择升序或降序
    query = queryParams.OrdenarSentido == SortDirection.Ascending
        ? query.OrderBy(queryParams.Ordenar)
        : query.OrderByDescending(queryParams.Ordenar);
}
// 如果前端没传排序参数,给个默认排序,比如按ID降序
else
{
    query = query.OrderByDescending(a => a.IdArticulo);
}

四、分页逻辑:计算总条数+截取数据

分页的核心是要返回总记录数,这样Angular前端才能算出总页数,咱们这么做:

// 先算总记录数,这一步EF Core会生成Count查询,性能没问题
int totalRecords = query.Count();

// 处理分页参数,如果默认的-1就返回全部数据,否则跳过指定条数取对应数量
if (queryParams.RegistroInic != -1 && queryParams.Registros != -1)
{
    query = query.Skip(queryParams.RegistroInic).Take(queryParams.Registros);
}

// 执行查询获取数据
var result = query.ToList();

// 返回包含数据和总条数的对象,前端拿到就能直接用
return Ok(new 
{
    Data = result,
    TotalRecords = totalRecords
});

五、给你几个额外的实用建议

  • 加参数验证:给ArticleQueryParams的属性加DataAnnotations,比如给Registros加[Range(1, 100)]限制每页最多100条,避免前端传过大的数拖垮数据库
  • 异常处理:给数据库操作加try-catch,捕获异常后返回BadRequest或者StatusCode(500),别让错误直接抛给前端
  • 性能优化:给经常用来过滤、排序的字段加数据库索引,比如Activos、Source、Titulo这些
  • 避免SQL注入:全程用EF Core的Linq查询,别自己拼接SQL字符串,Linq会自动参数化,安全得很

最后提下Angular前端配合

前端请求时把分页、排序、过滤参数都拼在URL的查询参数里,收到后端返回的TotalRecords后,用它和每页条数算出总页数,更新分页组件的状态就行,排序和过滤触发时重新发送请求就OK。

内容的提问来源于stack exchange,提问作者ericpap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:02:11