ASP.NET Core Razor Pages分页链接适配多选框字符串数组方法
解决ASP.NET Core Razor Pages分页链接适配字符串数组过滤条件的问题
刚好我之前在做Razor Pages项目时也遇到过类似的多选过滤分页问题,咱们一步步来调整代码解决它:
1. 先调整后端PageModel代码
修改属性和参数类型
把原来单个字符串类型的CurrentFilter、searchString、currentFilter全部改成字符串数组,适配多选下拉框的参数传递:
public string CurrentSort { get; set; } public string[] CurrentFilter { get; set; } // 从string改为string[] public string NameSort { get; set; } public string DateSort { get; set; } public PaginatedList<Student> Student { get; set; } private readonly SchoolContext _context; public IndexModel(SchoolContext context) { _context = context; } public async Task OnGetAsync(string sortOrder, string[] currentFilter, string[] searchString, int? pageIndex) { CurrentSort = sortOrder; NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; DateSort = sortOrder == "Date" ? "date_desc" : "Date"; // 处理搜索参数变化时重置分页的逻辑 if (searchString != null && searchString.Any()) { pageIndex = 1; } else { searchString = currentFilter; } CurrentFilter = searchString; // 构建基础查询 IQueryable<Student> studentIQ = from s in _context.Student select s; // 适配数组类型的过滤逻辑(这里要根据你的多选下拉框实际值调整,比如我假设是匹配学生的姓氏或名字) if (searchString != null && searchString.Any()) { studentIQ = studentIQ.Where(s => searchString.Contains(s.LastName) || searchString.Contains(s.FirstMidName)); } // 排序逻辑保持和原来一致就行 switch (sortOrder) { case "name_desc": studentIQ = studentIQ.OrderByDescending(s => s.LastName); break; case "Date": studentIQ = studentIQ.OrderBy(s => s.EnrollmentDate); break; case "date_desc": studentIQ = studentIQ.OrderByDescending(s => s.EnrollmentDate); break; default: studentIQ = studentIQ.OrderBy(s => s.LastName); break; } int pageSize = 3; Student = await PaginatedList<Student>.CreateAsync( studentIQ.AsNoTracking(), pageIndex ?? 1, pageSize); // 新增:创建路由数据字典,给前端分页链接用 ViewData["RouteData"] = new Dictionary<string, object> { { "sortOrder", CurrentSort }, { "currentFilter", CurrentFilter } }; }
注意过滤逻辑的适配
这里的Where子句是我根据常见场景写的,你要根据自己多选下拉框的实际业务逻辑调整,比如如果是按班级ID过滤,就改成searchString.Contains(s.ClassId.ToString())之类的。
2. 再调整前端cshtml的分页链接
asp-route-*标签助手没法直接传递数组,但我们可以用asp-all-route-data来传递包含数组的路由参数集合,这样最省心:
<a asp-page="./Index" asp-all-route-data="@ViewData["RouteData"]" asp-route-pageIndex="@(Model.Student.PageIndex - 1)" class="btn btn-default @prevDisabled"> Previous </a> <a asp-page="./Index" asp-all-route-data="@ViewData["RouteData"]" asp-route-pageIndex="@(Model.Student.PageIndex + 1)" class="btn btn-default @nextDisabled"> Next </a>
备选方案:手动生成多个同名参数
要是你不想用字典,也可以手动为数组里的每个元素生成一个asp-route-currentFilter参数(ASP.NET Core会自动把多个同名参数绑定成数组),不过代码会繁琐点:
@{ var prevLinkAttrs = new Dictionary<string, object> { { "class", $"btn btn-default {prevDisabled}" }, { "asp-route-sortOrder", Model.CurrentSort }, { "asp-route-pageIndex", Model.Student.PageIndex - 1 } }; if (Model.CurrentFilter != null) { foreach (var filter in Model.CurrentFilter) { prevLinkAttrs.Add("asp-route-currentFilter", filter); } } } <a asp-page="./Index" @foreach (var attr in prevLinkAttrs) { @attr.Key="@attr.Value" }> Previous </a> @{ var nextLinkAttrs = new Dictionary<string, object> { { "class", $"btn btn-default {nextDisabled}" }, { "asp-route-sortOrder", Model.CurrentSort }, { "asp-route-pageIndex", Model.Student.PageIndex + 1 } }; if (Model.CurrentFilter != null) { foreach (var filter in Model.CurrentFilter) { nextLinkAttrs.Add("asp-route-currentFilter", filter); } } } <a asp-page="./Index" @foreach (var attr in nextLinkAttrs) { @attr.Key="@attr.Value" }> Next </a>
还是推荐第一种用asp-all-route-data的方案,代码更简洁。
3. 最后验证一下
运行项目后点击分页链接,你会看到URL里生成类似?sortOrder=¤tFilter=Smith¤tFilter=Johnson&pageIndex=2的参数,ASP.NET Core会自动把这些同名的currentFilter参数绑定到后端的string[]类型参数里,完美适配你的多选下拉框过滤需求。
内容的提问来源于stack exchange,提问作者AndyL
相关产品推荐
相关产品推荐

