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

JToken递归集合数据契约不支持报错,能否避免使用Newtonsoft处理?

报错根源分析
Type 'Newtonsoft.Json.Linq.JToken' is a recursive collection data contract which is not supported. Consider modifying the definition of collection 'Newtonsoft.Json.Linq.JToken' to remove references to itself.
  • 该报错触发于service.Create(history)执行阶段,并非JSON解析阶段:你直接将JToken派生类型的对象(item.No/item["No"]本质都是Newtonsoft的JValue类型,继承自JToken)赋值给了Entity的属性字段,当底层服务尝试序列化Entity对象提交时,会检测到JToken类型存在自引用的递归结构,WCF/Dataverse的序列化器不支持这类类型,因此抛出异常。
  • 你修改后的代码仍然直接传递item["No"]这个JToken对象给Entity属性,未做基础类型转换,所以还是触发相同报错。
无Newtonsoft的实现方案

根据你使用的.NET版本选择对应内置方案即可:

方案1:.NET Framework 环境(适配HttpWebRequest写法)

先引用程序集System.Web.Extensions,替换JSON解析逻辑:

string url = $"***";
tracingService.Trace(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
NetworkCredential myNetworkCredential = new NetworkCredential("***@***.**", "***");
request.Credentials = myNetworkCredential;
request.ContentType = "application/json";

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusDescription == "OK")
{
    Stream dataStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(dataStream);
    string responseFromServer = reader.ReadToEnd();
    tracingService.Trace(responseFromServer);

    // 用.NET内置序列化器,完全不需要Newtonsoft
    var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    dynamic result = serializer.Deserialize<dynamic>(responseFromServer);
    var items = result["value"];

    foreach (var item in items)
    {
        // 每次循环创建新Entity,不要复用同一个实例
        Entity history = new Entity("zst_casehistory");
        // 转成基础字符串类型再赋值,禁止直接传解析器的包装类型
        string no = item["No"].ToString();
        tracingService.Trace(no);
        history["zst_servicereceiptno"] = no;
        service.Create(history);
    }
}

方案2:.NET Core/.NET 5+ 环境

使用内置的System.Text.Json解析:

using System.Text.Json;

// 前面请求逻辑不变,或者替换为更推荐的HttpClient写法
// ...省略Http请求部分代码...
string responseFromServer = reader.ReadToEnd();
tracingService.Trace(responseFromServer);

using JsonDocument doc = JsonDocument.Parse(responseFromServer);
JsonElement root = doc.RootElement;
JsonElement items = root.GetProperty("value");

foreach (JsonElement item in items.EnumerateArray())
{
    Entity history = new Entity("zst_casehistory");
    // 显式转成基础类型再赋值
    string no = item.GetProperty("No").GetString();
    tracingService.Trace(no);
    history["zst_servicereceiptno"] = no;
    service.Create(history);
}
额外注意事项
  • 不要在循环外复用同一个Entity实例,每次创建新的实例,避免出现重复数据提交、主键冲突等问题。
  • 所有从JSON中取出的值都要转换为string/int/DateTime等基础类型后再赋值给Entity属性,绝对不能直接传递JSON解析库的封装类型。

内容的提问来源于stack exchange,提问作者cryptoStp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:39:03