欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > Newtonsoft.Json.JsonSerializationException

Newtonsoft.Json.JsonSerializationException

2026/2/1 16:02:05 来源:https://blog.csdn.net/Dsxrrwe/article/details/147986176  浏览:    关键词:Newtonsoft.Json.JsonSerializationException

前言:

1 本文中内容全部手敲,如果存在错误,请在评论区指正

2 本文作学习探索使用,不涉及任何商业用途

3 本文会随着作者在软件开发过程中遇到问题,解决问题后不定期更新

一 自引用循环错误(self referencing loop)

1.1 错误原因

        对象之间存在循环引用(A 引用 B,B 又引用 A)

1.2 常见场景

1.2.1  异步任务状态机(AsyncTaskMethodBuilder

        ① 如何理解

                异步任务状态机是比较官方说法,你可以理解为异步任务(Task)返回的对象未完成就被调用序列化方法了。

        ② 真实原理

                一些编程语言,例如C# 会在编译(生成解决方案或者程序集的阶段)的时候生成一个状态机类(继承自IAsyncStateMachine),比如你的异步方法名称叫做 CreateFHDInput, 那么就会可能生成一个<CreateFHDInput>d__13 的类。其中d标识状态机类,13标识一个自增后缀,用于区分同名的多个生成类。 这个<CreateFHDInput>d__13 中有三个属性。

        I 当前的执行状态(_state)

        II 任务构造器(<>t_builder 类型为AsyncTaskMethodBuilder<T>)

        III 局部变量和上下文(_locals)

上面的变量之间相互引用,所以当你序列化一个未完成的任务返回对象时就会导致自引用循环错误

        ③ 错误复现

        下面的代码中CreateFHDInput是个异步方法 并返回一个对象

foreach (var item in input)
{ywy=await FindYWY(data1, item.YWY);var content =  CreateFHDInput(item, isCancel);string jsonContent = JsonConvert.SerializeObject(content);var res = await Request(jsonContent, Tools.RequestMethods.POST);await InsertAPIRecord(res, db, item.FHDH+item.FHHH.ToString("D3"), isCancel,Consts.LX_S);
}

在这个示例中,异步方法并没有使用await等待 任务执行完成,断点调试结果如下

因为未完成此任务,content对象仍然是一个状态机类的对象,状态是waitingforActivation等待任务结束。这是调用序列化方法就会导致循环引用报错。

        ④ 正确示例

        任务前加上await

foreach (var item in input)
{ywy=await FindYWY(data1, item.YWY);var content = await CreateFHDInput(item, isCancel);string jsonContent = JsonConvert.SerializeObject(content);var res = await Request(jsonContent, Tools.RequestMethods.POST);await InsertAPIRecord(res, db, item.FHDH+item.FHHH.ToString("D3"), isCancel,Consts.LX_S);
}

⑤: 解决方案

        I 使用await等待任务结束

        II 配置序列化设置忽略循环引用 (此方式我未验证)

// Newtonsoft.Json 配置
var settings = new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore // 忽略循环引用
};
string json = JsonConvert.SerializeObject(yourObject, settings);// System.Text.Json 配置
var options = new JsonSerializerOptions {ReferenceHandler = ReferenceHandler.IgnoreCycles // .NET 6+ 支持
};
string json = JsonSerializer.Serialize(yourObject, options);

二 待更新

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词