X++中反序列化含泛型列表的JSON问题求助
X++反序列化C#库泛型列表JSON的问题解决
问题核心
你在X++中处理泛型类型时遇到以下问题:
- 使用
JsonConvert::DeserializeObject能成功得到C#类实例,但无法直接访问其中的List<exceptionDetailList>元素 - 尝试
FormJsonSerializer::deserializeCollection未成功 - 疑惑X++的JSON序列化工具是否仅支持AX原生类,无法处理引用的C#库类
原因分析
X的类型系统与.NET不完全兼容,对.NET泛型集合的直接操作支持有限。虽然JsonConvert能正确反序列化生成List<T>对象,但X无法直接识别泛型集合的元素类型,导致无法直接遍历或访问元素。
解决方案
方案1:修改C#类,提供X++友好的访问方式
在C#辅助类中添加返回数组的属性,X++对.NET数组的支持更完善:
public class MyException { public string serviceCtx { get; set; } public string serviceCode { get; set; } public string serviceName { get; set; } public string timestamp { get; set;} public string referenceNumber { get; set; } // 保留原泛型列表供C#使用 public List<exceptionDetailList> exceptionDetailList { get; set; } // 添加数组属性供X++访问 public exceptionDetailList[] ExceptionDetailsArray => exceptionDetailList?.ToArray(); }
之后在X++中直接访问数组属性:
defaultException defaultException = new defaultException(); defaultException = JsonConvert::DeserializeObject(response, defaultException.GetType()); exceptionDetailList detail; for (int i = 0; i < defaultException.exception.ExceptionDetailsArray.Length; i++) { detail = defaultException.exception.ExceptionDetailsArray.GetValue(i); info(strFmt("异常代码:%1,描述:%2", detail.exceptionCode, detail.exceptionDescription)); }
方案2:在X++中通过反射遍历泛型列表
利用.NET反射机制,获取泛型列表的枚举器来遍历元素:
defaultException defaultException = new defaultException(); defaultException = JsonConvert::DeserializeObject(response, defaultException.GetType()); System.Collections.IEnumerator enumerator; exceptionDetailList detail; // 获取泛型列表的枚举器 enumerator = defaultException.exception.exceptionDetailList.GetEnumerator(); while (enumerator.MoveNext()) { // 显式转换当前元素到目标类型 detail = CLRInterop::cast(enumerator.Current, exceptionDetailList::GetType()); info(strFmt("异常代码:%1,描述:%2", detail.exceptionCode, detail.exceptionDescription)); }
方案3:正确使用FormJsonSerializer
FormJsonSerializer::deserializeCollection适用于反序列化到AX原生的List对象,若要反序列化到C#类,应使用deserializeObject:
defaultException defaultException; System.Type targetType = CLRInterop::getType('你的命名空间.defaultException'); defaultException = FormJsonSerializer::deserializeObject(targetType, response) as defaultException; // 后续通过方案1的数组属性或方案2的反射访问列表元素
注意:FormJsonSerializer对.NET泛型的支持不如JsonConvert,优先推荐前两种方案。
关键结论
JsonConvert可以正确处理C#泛型类的反序列化,但X++无法直接操作泛型集合元素,需通过数组或反射间接访问FormJsonSerializer更适配AX原生类型,对引用的C#库类泛型支持有限- 修改C#类提供X++友好的访问方式是最简洁的解决途径
内容的提问来源于stack exchange,提问作者Tweene
相关产品推荐
相关产品推荐

