Ajax解析JSON报Cannot read properties of undefined属性读取错误
问题现象
在Ajax解析后端返回的JSON数据做组件赋值操作时,触发如下报错:
Uncaught TypeError: Cannot read properties of undefined (reading 'GrossSalesPriceForUser')
实现场景:后端Controller定义业务实体类,实例化赋值后将数据传递到View层,前后端代码如下。
原问题代码
Controller层(C#)
public class CalsEarlyStatementForUser { public decimal GrossSalesPriceForUser { get; set; } public decimal PaidBeneficiaryForUser { get; set; } } //(...) //接口方法逻辑 CalsEarlyStatementForUser objCalsEarlyStatementForUser = new CalsEarlyStatementForUser(); objCalsEarlyStatementForUser.GrossSalesPriceForUser = grossSalesPriceForUser; objCalsEarlyStatementForUser.PaidBeneficiaryForUser = paidBeneficiaryForUser; var jsonData = JsonConvert.SerializeObject(objCalsEarlyStatementForUser); return Json(jsonData);
View层(Ajax请求)
$.ajax({ url: "@Url.Action("CalcEarlyStatement", "Calculations")", type: "GET", dataType: "json", contentType: "application/json; charset=utf-8", data: {"data": JSON.stringify(data)}, cache: false, success: function (result) { // 此处执行报错 $("#GrossSalesPriceForUser") .dxNumberBox("instance") .option("value", result.objCalsEarlyStatementForUser.GrossSalesPriceForUser); $("#PaidBeneficiaryForUser") .dxNumberBox("instance") .option("value", result.objCalsEarlyStatementForUser.PaidBeneficiaryForUser); }, failure: function (error) { alert(error); }, error: function (error) { alert(error); } });
报错原因
一共两个核心问题:
- 后端重复序列化:先用
JsonConvert.SerializeObject把实体对象转成了JSON字符串,再调用ASP.NET MVC内置的Json()方法返回结果,相当于对字符串做了二次JSON序列化。最终前端拿到的result是转义后的字符串,不是预期的结构化对象,本身不存在自定义业务属性。 - 前端取值层级错误:即使后端序列化逻辑正确,返回的JSON结构也是直接包含
GrossSalesPriceForUser、PaidBeneficiaryForUser两个属性的平面对象,不存在外层的objCalsEarlyStatementForUser字段——这个字段只是后端C#代码里的变量名,序列化时不会作为属性名输出。多写一层属性访问自然会读到undefined,再取子属性就会触发类型错误。
修复方案
- 修正后端返回逻辑:去掉手动序列化步骤,直接将实体对象传入
Json()方法,由框架完成序列化;同时GET请求返回JSON需要显式指定允许GET请求,避免框架拦截报错。
修正后的Controller返回代码:CalsEarlyStatementForUser objCalsEarlyStatementForUser = new CalsEarlyStatementForUser(); objCalsEarlyStatementForUser.GrossSalesPriceForUser = grossSalesPriceForUser; objCalsEarlyStatementForUser.PaidBeneficiaryForUser = paidBeneficiaryForUser; // 直接返回实体对象,无需手动转JSON字符串 return Json(objCalsEarlyStatementForUser, JsonRequestBehavior.AllowGet); - 修正前端取值逻辑:去掉多余的
objCalsEarlyStatementForUser层级,直接从result对象读取目标属性。
修正后的success回调代码:success: function (result) { $("#GrossSalesPriceForUser") .dxNumberBox("instance") .option("value", result.GrossSalesPriceForUser); $("#PaidBeneficiaryForUser") .dxNumberBox("instance") .option("value", result.PaidBeneficiaryForUser); },
排查小技巧:如果不确定接口返回的实际结构,可以在success回调第一行加console.log(result)打印返回值,对照结构调整属性访问路径即可。
内容的提问来源于stack exchange,提问作者Michael1834
相关产品推荐
相关产品推荐

