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

Kendo MVC服务端分页配置后Grid选中页码始终为1问题求助

Kendo 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:27:03