Kendo MVC服务端分页配置后Grid选中页码始终为1问题求助
问题现象
配置了服务端分页的Kendo Grid,前端切换任意页码,后端控制器接收到的DataSourceRequest.Page始终为1。
视图代码
@(Html.Kendo().Grid<Models.Employee>() .Name("empGrid") .Columns(column => { column.Bound(emp => emp.Tickets).Title("Tickets").Filterable(false).Sortable(false) .ClientTemplate("<div style='display:flex;align-items:center;'> " + " #= getLateTicketIcon(DueDate) # " "</div>").Width(100); column.Bound(emp => emp.EmpID).Hidden(); column.Bound(emp => emp.DeptID).Hidden(); column.Bound(emp => emp.Name).Title("Name#").Width(100); column.Bound(emp => emp.TicketNumber).Width(150).ClientTemplate("#= getEempTickets(EmpID, DeptID) # "); column.Bound(emp => emp.DueDate).Width(150) .ClientTemplate("#: DueDate === null ? '' : kendo.toString(getDateAsUTC(kendo.parseDate(DueDate)), 'MM/dd/yyyy') #"); }) .NoRecords("There are no records to display") .Sortable() .Scrollable(scrollable => scrollable.Height("auto")) .Pageable(pager => pager .PageSizes(new[] { 10, 25, 50, 100, 200 }) .Refresh(true) .Input(true)) .Filterable() .Resizable(resizable => resizable.Columns(true)) .Reorderable(reorder => reorder.Columns(true)) .Excel(ex => { ex.AllPages(true); ex.Filterable(true); }) .DataSource(dataSource => dataSource .Ajax() .PageSize(50) .ServerOperation(true) .Read(read => read.Action("GetTickets", "Employee").Data("readFromServerWithParameters").Type(HttpVerbs.Get))) .Events(ev => ev.DataBound("currentGridDataBound")) .AutoBind(false))
控制器代码
[HttpGet] [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] public ActionResult GetTickets([DataSourceRequest] DataSourceRequest request, long? empID, string[] searchOptions) { List<Employee> results = repo.GetTickets(empID, searchOptions,request.Page,request.PageSize); JsonResult resultJson = Json(results.ToDataSourceResult(request), JsonRequestBehavior.AllowGet); resultJson.MaxJsonLength = int.MaxValue; return resultJson; }
问题根因及对应解决方案
根因1:返回的总记录数错误
你当前的查询逻辑是先自行做了分页拿到当前页数据,再调用ToDataSourceResult方法,该方法会默认把传入的集合长度作为总记录数返回给前端。前端拿到的总条数≤单页容量时,会判定只有1页,下次翻页时自动重置页码为1。
解决方案:
调整仓储层方法,同时返回当前页数据和全量符合条件的总记录数,手动构造返回结果:// 调整仓储方法,返回元组(当前页数据, 总记录数) var (results, totalCount) = repo.GetTickets(empID, searchOptions,request.Page,request.PageSize); var dataSourceResult = new DataSourceResult { Data = results, Total = totalCount }; return Json(dataSourceResult, JsonRequestBehavior.AllowGet);根因2:自定义请求参数方法覆盖了Kendo自带的分页参数
你在Read配置中指定了Data("readFromServerWithParameters")自定义参数方法,如果该方法的返回值中包含page字段,就会覆盖Kendo自动生成的页码参数,固定为1。
解决方案:
调整readFromServerWithParameters方法,只返回自定义业务参数,不要返回page、pageSize、sort、filter等Kendo自动管理的参数:function readFromServerWithParameters() { return { empID: $('#empSelector').val(), searchOptions: $('#searchArea input:checked').map(function(){return this.value}).get() // 禁止添加 page:1 这类代码 }; }根因3:数组参数模型绑定失败
GET请求下数组参数默认绑定规则不匹配,导致DataSourceRequest整体模型绑定失败,Page属性取默认值1。
解决方案:
给数组参数添加[FromQuery]注解,适配GET请求参数绑定:public ActionResult GetTickets([DataSourceRequest] DataSourceRequest request, long? empID, [FromQuery] string[] searchOptions)根因4:前端逻辑强制重置页码
检查currentGridDataBound等绑定事件中,是否存在调用$('#empGrid').data('kendoGrid').dataSource.page(1)的代码,这类逻辑会在数据加载完成后强制重置页码为1。
解决方案:移除不必要的强制重置页码逻辑即可。
内容的提问来源于stack exchange,提问作者Michael Edwards

