.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
相关产品推荐
相关产品推荐

