Newtonsoft:将 json 字符串解析为对象时出现“已超出读者的 MaxDepth 64”错误
Posted
技术标签:
【中文标题】Newtonsoft:将 json 字符串解析为对象时出现“已超出读者的 MaxDepth 64”错误【英文标题】:Newtonsoft: Getting "The reader's MaxDepth of 64 has been exceeded" error while parse json string into object 【发布时间】:2021-10-05 03:53:42 【问题描述】:我正在尝试解析 json 字符串以创建 DialogState 对象。但是在某种程度上,我在将 JSON 字符串解析为对象时遇到了以下错误:
The reader's MaxDepth of 64 has been exceeded. Path 'DialogState.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.dialogs.dialogStack.$values[0].state.options.Prompt.attachments.$values', line 1, position 7999.
我正在使用以下方法来序列化和反序列化我的对象:
//**For serialize**
var _jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings TypeNameHandling = TypeNameHandling.All, MaxDepth = 128 );
var json = JObject.FromObject(change.Value, _jsonSerializer);
var jsonString = json.ToString(Formatting.None);
//**For deserialize**
var jObject = JObject.Parse(jsonString).ToObject(typeof(object), _jsonSerializer);
【问题讨论】:
【参考方案1】:在 Json.NET 13.0.1 中,Newtonsoft 将 JsonReader
(以及包括 JsonTextReader
在内的所有派生阅读器类型)的默认 MaxDepth
更改为 64:
更改 - JsonReader 和 JsonSerializer MaxDepth 默认为 64
但是,他们没有将 MaxDepth
添加到 JsonLoadSettings
,因此如果输入 JSON 深度超过 64 级,JObject.Parse()
(以及 JArray.Parse()
和 JToken.Parse()
)现在将抛出。
避免这种情况的最简单方法是改用JsonConvert.DeserializeObject<JObject>(string, JsonSerializerSettings)
并将JsonSerializerSettings.MaxDepth
设置为较大的值,就像您当前在序列化时所做的那样:
var settings = new JsonSerializerSettings TypeNameHandling = TypeNameHandling.All, MaxDepth = 128 ;
var _jsonSerializer = JsonSerializer.Create(settings);
var jObject = JsonConvert.DeserializeObject<JObject>(jsonString, settings).ToObject(typeof(object), _jsonSerializer);
注意事项:
似乎已添加MaxDepth
限制以避免某种拒绝服务警告,有关详细信息,请参阅ALEPH-2018004 - DOS vulnerability #2457。
似乎没有充分的理由先解析为JObject
,然后反序列化为object
。默认情况下,当反序列化为object
(除非被TypeNameHandling
覆盖)时,无论如何,Json.NET 都会将 JSON 对象反序列化为JObject
,所以你可以这样做
var jObject = JsonConvert.DeserializeObject<object>(jsonString, settings);
从而避免了不必要的步骤。
如果您使用TypeNameHandling
,出于安全原因,您可能需要提供自定义ISerializationBinder
。请参阅 TypeNameHandling caution in Newtonsoft Json 了解原因。
【讨论】:
以上是关于Newtonsoft:将 json 字符串解析为对象时出现“已超出读者的 MaxDepth 64”错误的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Newtonsoft.Json 将包含数组数组的 json 对象解析为 C# 中的对象列表?