FreemarketNet视图无法读取JSON嵌套属性,如何获取指定值?
解决FreeMarker视图无法访问JObject属性的问题
嘿,我来帮你搞定这个问题!你现在遇到的核心问题是:你传到视图的JObject在FreeMarker里被当成了普通字符串,而不是可遍历的对象结构。因为JObject默认的ToString()方法会直接输出JSON格式的字符串,所以你直接渲染${Recipient}看到的是完整的JSON文本,但没法用点语法去访问内部的属性值。
下面给你几个可行的解决方案,按需选择:
方案1:把JObject转成动态ExpandoObject
在控制器里把JObject转换成ExpandoObject,这样FreeMarker就能识别它的属性,轻松用点语法访问:
using Newtonsoft.Json; using System.Dynamic; // 你的原有代码 dynamic obj = JObject.Parse("{'contact':{ 'cx_outstandingamountid':{ 'cx_outstandingamount':'ytest' } } }"); // 新增:把JObject转成ExpandoObject dynamic expando = JsonConvert.DeserializeObject<ExpandoObject>(obj.ToString()); ViewData["data"] = expando; return View();
然后视图里就可以正常写了:
<#import "../Shared/Master.ftl" as layout /> <#assign TitleContent in layout> Home Page </#assign> <#assign Recipient = controller.ViewData.data> ${Recipient.contact.cx_outstandingamountid.cx_outstandingamount}
方案2:转成IDictionary<string, object>
另一种简单的方式是把JObject转成字典,FreeMarker支持直接通过键(点语法也适用)访问字典里的值:
控制器代码修改:
dynamic obj = JObject.Parse("{'contact':{ 'cx_outstandingamountid':{ 'cx_outstandingamount':'ytest' } } }"); // 转成字典 var dataDict = obj.ToObject<IDictionary<string, object>>(); ViewData["data"] = dataDict; return View();
视图里的访问方式和方案1完全一样,不用改。
方案3:定义强类型实体类(推荐长期项目)
如果这个数据结构是固定不变的,最稳妥的方式是创建对应的实体类,类型更安全,后续维护也方便:
先写实体类:
public class OutstandingAmount { public string cx_outstandingamount { get; set; } } public class ContactInfo { public OutstandingAmount cx_outstandingamountid { get; set; } } public class RecipientData { public ContactInfo contact { get; set; } }
然后控制器里反序列化成实体类:
var jsonString = "{'contact':{ 'cx_outstandingamountid':{ 'cx_outstandingamount':'ytest' } } }"; var recipientData = JsonConvert.DeserializeObject<RecipientData>(jsonString); ViewData["data"] = recipientData; return View();
视图里还是用同样的点语法访问就行。
为啥原来的写法不行?
因为JObject是Newtonsoft.Json专属的类型,FreeMarker的视图引擎没办法直接解析它的内部属性结构,只能调用它的ToString()方法输出JSON字符串。所以只要把它转换成FreeMarker能识别的动态对象、字典或者强类型对象,就能正常访问属性啦。
内容的提问来源于stack exchange,提问作者Sujatha
相关产品推荐
相关产品推荐

