Kendo MVC Grid子网格无法加载数据及参数ID为空错误求助
刚帮同事踩过Kendo子网格的坑,这俩问题我都遇到过,给你唠唠具体怎么解决:
问题1:子网格展开无内容,控制器Read事件未触发
这个问题大概率是父行参数没传对或者子网格数据源配置有问题,按下面的步骤排查:
先检查父网格的主键配置:
父网格必须明确设置主键,子网格才能拿到父行的ID,比如:.Model(model => model.Id(p => p.UserID)) // 这里的UserID是父表的主键字段用
DetailInit事件手动初始化子网格(比模板方式更易排查):
别用默认的DetailTemplate,直接写JS函数初始化子网格,确保父ID能正确传递:function detailInit(e) { // e.data就是当前展开的父行数据,直接拿UserID $("<div class='subgrid'></div>").appendTo(e.detailCell).kendoGrid({ dataSource: { type: "aspnetmvc-ajax", transport: { read: { url: "@Url.Action("ReadBalances", "YourController")", // 直接把父行ID作为参数传递 data: { userId: e.data.UserID } } }, serverPaging: true, serverFiltering: true }, columns: [ { field: "BalanceDate", title: "日期" }, { field: "Amount", title: "余额" } ], pageable: true, filterable: true }); }然后父网格配置这个事件:
.DetailInit("detailInit")用浏览器F12抓包验证:
展开父行时,看Network面板有没有发送到ReadBalances的请求,如果没有,大概率是JS函数写错了(比如函数名拼写错误,或者父行字段名不对);如果有请求但参数为空,检查e.data.UserID是不是父行实际存在的字段。
问题2:筛选子网格时,Read方法报“id参数为空”错误
这个是因为筛选时子网格会重新发起请求,但默认不会自动带上父行ID,得手动确保每次请求都传递这个参数:
统一参数名称,避免前后端不匹配:
前端传递的参数名要和控制器方法的参数名完全一致!比如前端传userId,控制器就得写:public ActionResult ReadBalances(DataSourceRequest request, int userId) { // 用userId查询数据 var data = yourService.GetBalancesByUserId(userId); return Json(data.ToDataSourceResult(request)); }如果控制器参数是
int id,那前端就要传id: e.data.UserID,别搞混了!给子网格容器绑定父ID,筛选时动态获取:
如果用了DetailTemplate方式,或者担心筛选时丢失父ID,可以给子网格的容器加个data属性存父ID:function detailInit(e) { var detailCell = e.detailCell; // 把父ID存在detailCell的data属性里 detailCell.data("userid", e.data.UserID); $("<div class='subgrid'></div>").appendTo(detailCell).kendoGrid({ dataSource: { type: "aspnetmvc-ajax", transport: { read: { url: "@Url.Action("ReadBalances", "YourController")", data: function() { // 每次请求都从detailCell里拿父ID return { userId: detailCell.data("userid") }; } } }, serverFiltering: true }, // 其他配置... }); }这样不管是首次加载还是筛选、分页,都会自动带上父ID参数。
排查控制器参数是否允许为空:
如果你的id参数没加int?(可空int),又没传值,就会报那个错误。如果业务上允许ID为空,就改成int? id,但子网格肯定是依赖父ID的,所以更建议确保参数必传。
最后再给你两个排查小技巧
- 打开浏览器控制台,看有没有JS报错,很多时候子网格不加载是因为JS语法错误;
- 在控制器的
ReadBalances方法开头加个断点,看请求有没有进来,参数值是什么,能快速定位问题。
内容的提问来源于stack exchange,提问作者AngelRuizC

