Kendo Ajax Grid无法渲染已获取数据,求技术解决方案
Kendo Ajax Grid 获取数据后无法渲染的问题
已确认的排查信息
- 浏览器网络面板及Fiddler均捕获到控制器返回的完整JSON数据
- 通过前端代码
$("#grid").data("kendoGrid")._data和$("#grid").data("kendoGrid").dataItems()验证,Grid数据源为空
控制器代码
[HttpPost, HttpGet] public ActionResult SavedSettings_Read([DataSourceRequest] DataSourceRequest request) { var ret = DBFunctions.SavedStringInfos.ToDataSourceResult(request); //return Json( ret); made everything lowercase? return JsonConvert.SerializeObject(ret);//newtonsoft }
Grid 定义(ASP.NET MVC Razor)
Html.Kendo().Grid<SavedStringInfo>() .Name("grid") .Pageable() .Sortable() .Filterable() .Scrollable() .Editable(editable => editable.Mode(GridEditMode.InLine)) .DataSource(data => { data.Ajax() .PageSize(20) .Model(x => x.Id(p => p.IPAddress)) .Create("SavedSettings_Create", "Home") .Read("SavedSettings_Read", "Home") .Update("SavedSettings_Update", "Home") .Destroy("SavedSettings_Destroy", "Home"); }) .HtmlAttributes(new { style = "height:430px;" }) .ToolBar(t => t.Create().Text("Add New Device(s)")) .Columns( columns => { columns.Command(x => { x.Edit(); x.Destroy(); }); columns.Bound(m => m.StreamTo).Title("Stream To").Width(120); columns.Bound(m => m.StringName).Title("String Name").Width(200); columns.Group(g => { g.Title("Channels"); g.Columns(gc => { gc.Bound(m => m.StartChannel).Title("Start").Width(100); gc.Bound(m => m.EndChannel).Title("End").Width(100); }); }); columns.Bound(m => m.DisableFrameLimiter).Title("DFL").Width(100); columns.Bound(m => m.IPAddress).Title("IP Address").Width(160); columns.Bound(m => m.MacAddress).Title("MAC Address)").Width(160); columns.Group(g => { g.Title("Aspect Ratio"); g.Columns(gc => { gc.Bound(m => m.XYAspectRatio).Title("XY").Width(100); gc.Bound(m => m.XZAspectRatio).Title("XZ").Width(100); }); }); })
返回的JSON数据
{ "Data": [ { "ID": 1, "StringName": "Line in bedroom", "StartChannel": 1, "IPAddress": "192.168.4.166", "MacAddress": "a8:03:2a:3e:76:95", "StreamTo": true, "XYAspectRatio": 0.8, "XZAspectRatio": 0, "DisableFrameLimiter": true }, { "ID": 2, "StringName": "Right poles", "StartChannel": 1, "IPAddress": "192.168.4.36", "MacAddress": "a4:e5:7c:c4:75:01", "StreamTo": true, "XYAspectRatio": 0.45455, "XZAspectRatio": 11.36364, "DisableFrameLimiter": true }, { "ID": 3, "StringName": "Left poles", "StartChannel": 1, "IPAddress": "192.168.4.37", "MacAddress": "a4:e5:7c:5e:6f:f9", "StreamTo": true, "XYAspectRatio": 0.5, "XZAspectRatio": 11.36364, "DisableFrameLimiter": true } ], "Total": 3, "AggregateResults": null, "Errors": null }
问题原因及修复方案
核心问题:控制器返回格式错误
当前控制器直接返回JsonConvert.SerializeObject(ret)生成的JSON字符串,但Kendo Grid的Ajax数据源期望的是标准的application/json类型响应(由MVC的JsonResult提供)。直接返回字符串会导致Grid无法正确解析响应内容,从而无法填充数据源。
附加问题:属性大小写不匹配
你提到默认Json(ret)会将属性转为小写,这是因为.NET默认序列化器(System.Text.Json)默认采用驼峰命名,而Grid的Model绑定依赖类的PascalCase(大驼峰)属性名。
修复步骤
修改控制器返回方式:
替换return JsonConvert.SerializeObject(ret);为MVC标准的Json()方法:[HttpPost, HttpGet] public ActionResult SavedSettings_Read([DataSourceRequest] DataSourceRequest request) { var ret = DBFunctions.SavedStringInfos.ToDataSourceResult(request); // ASP.NET MVC 5及以下需添加JsonRequestBehavior.AllowGet return Json(ret, JsonRequestBehavior.AllowGet); // ASP.NET Core 可直接写 return Json(ret); }配置MVC使用Newtonsoft.Json保持属性命名一致:
- 安装对应包:ASP.NET Core安装
Microsoft.AspNetCore.Mvc.NewtonsoftJson,ASP.NET MVC 5安装Newtonsoft.Json及Microsoft.AspNet.WebApi.Client - 配置序列化规则:
- ASP.NET Core(Startup.cs):
services.AddControllersWithViews() .AddNewtonsoftJson(options => { // 保持属性为PascalCase,与类定义一致 options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver(); }); - ASP.NET MVC 5(App_Start/WebApiConfig.cs):
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
- ASP.NET Core(Startup.cs):
- 安装对应包:ASP.NET Core安装
其他注意点
- 检查Grid中
EndChannel列的绑定:返回的JSON中无该字段,会导致此列显示空值,但不会影响整体数据渲染 - 确认Grid的Model主键
IPAddress在返回数据中是唯一值,这是Grid数据绑定的必要条件
内容的提问来源于stack exchange,提问作者John Lord
相关产品推荐
相关产品推荐

