You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:40:54