如何让XSuperObject中ISuperObject字段保持原JSON格式不被解析修改
问题:XSuperObject自动转换日期字段导致格式变更,如何保持原始JSON内容?
我们系统使用XSuperObject库在服务端与客户端间做对象和JSON的转换,服务端的VALUE字段为ISuperObject类型,客户端对应多种对象类型。需求是客户端发送对象到服务端后,服务端原封不动返回其中一个对象。
场景示例
发送的原始JSON:
[ { "NAME": "Today", "VALUE": {"loginIndex": 0,"shipmentDate": "2023-09-08","shipmentAddressId": "","paymentMethodId": "","shipmentMethodId": "","shipmentOfficeId": ""}, "IS_DEFAULT": false, "ID": 0, "WH_ID": 0 }, { "NAME": "Monday", "VALUE": {"loginIndex": 0,"shipmentDate": "2023-09-11","shipmentAddressId": "","paymentMethodId": "","shipmentMethodId": "","shipmentOfficeId": ""}, "IS_DEFAULT": false, "ID": 0, "WH_ID": 0 }, { "NAME": "Tuesday", "VALUE": {"loginIndex": 0,"shipmentDate": "2023-09-12","shipmentAddressId": "","paymentMethodId": "","shipmentMethodId": "","shipmentOfficeId": ""}, "IS_DEFAULT": false, "ID": 0, "WH_ID": 0 } ]
服务端转换用的记录结构:
TMySelectedItem = record NAME:String; VALUE:ISuperObject; IS_DEFAULT:Boolean; ID:Integer; WH_ID:Integer; end
问题现象
使用TSuperRecord<TMySelectedItem>.FromJSON(Resp.Data[i])将JSON转为对象,提取VALUE字段后用VALUE.AsJSON转字符串,预期结果:
{"loginIndex": 0,"shipmentDate": "2023-09-08","shipmentAddressId": "","paymentMethodId": "","shipmentMethodId": "","shipmentOfficeId": ""}
实际返回结果:
{"loginIndex": 0,"shipmentDate": "2023-09-07Z","shipmentAddressId": "","paymentMethodId": "","shipmentMethodId": "","shipmentOfficeId": ""}
XSuperObject自动将shipmentDate识别为日期类型,还在无时区信息的情况下修改了日期格式(添加Z后缀、变更日期值),但我们并未指定该字段为日期类型。请问能否标记ISuperObject类型字段,让它转换为JSON时保持原始内容不被修改?
解决方法
1. 全局禁用自动日期识别
XSuperObject默认会自动解析类日期格式的字符串为日期类型,可通过全局设置关闭该行为:
SuperObject.SO.DetectDate := False;
此设置会影响整个应用内的XSuperObject解析逻辑,所有类日期字符串都会被当作普通字符串处理,不会被转换为日期类型。
2. 局部处理:用字符串存储原始JSON
若不想全局修改,可将VALUE字段类型从ISuperObject改为String,直接存储原始JSON字符串。需要使用时再解析为ISuperObject,输出时直接返回原始字符串:
修改记录结构:
TMySelectedItem = record NAME:String; VALUE:String; // 改为字符串存储原始JSON内容 IS_DEFAULT:Boolean; ID:Integer; WH_ID:Integer; end
使用示例:
// 解析时保留VALUE的原始JSON字符串 var Item := TSuperRecord<TMySelectedItem>.FromJSON(Resp.Data[i]); // 需要操作VALUE内的内容时再解析为ISuperObject var ValueObj := SO(Item.VALUE); // 输出时直接返回Item.VALUE,无需二次转换
3. 自定义序列化逻辑(针对特定字段)
若必须保留ISuperObject类型,可手动处理目标字段,强制将其作为字符串输出:
var ValueObj := Item.VALUE; // 检查并强制将shipmentDate转为字符串格式 if ValueObj.Contains('shipmentDate') then begin ValueObj.S['shipmentDate'] := ValueObj.S['shipmentDate']; end; // 生成最终JSON var ResultJSON := ValueObj.AsJSON;
此方式适合字段固定的场景,需针对每个可能被误识别的字段单独处理。
内容的提问来源于stack exchange,提问作者vbif
相关产品推荐
相关产品推荐

