Reputation: 83
I am trying to parse json string to create DialogState object. However at some level I am getting following error while parsing a JSON string into an object:
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.
I am using following method to serialize and deserialize my object:
//**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);
Upvotes: 8
Views: 8894
Reputation: 116585
In Json.NET 13.0.1, Newtonsoft changed the default MaxDepth
for JsonReader
(and hence all derived reader types including JsonTextReader
) to 64:
Change - JsonReader and JsonSerializer MaxDepth defaults to 64
However, they did not add a MaxDepth
to JsonLoadSettings
, so JObject.Parse()
(as well as JArray.Parse()
and JToken.Parse()
) will now throw if the input JSON depth exceeds 64 levels.
The easiest way to avoid this is to use JsonConvert.DeserializeObject<JObject>(string, JsonSerializerSettings)
instead and set JsonSerializerSettings.MaxDepth
to something large, as you are currently doing when serializing:
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);
Notes:
The MaxDepth
limitation seems to have been added to avoid some sort of denial-of-service warning, see ALEPH-2018004 - DOS vulnerability #2457 for details.
There doesn't seem to be good reason to parse to a JObject
then deserialize to object
. By default Json.NET will deserialize a JSON object to a JObject
anyway when deserializing to object
(unless overridden by TypeNameHandling
), so you could just do
var jObject = JsonConvert.DeserializeObject<object>(jsonString, settings);
Thereby avoiding the unnecessary step.
If you are using TypeNameHandling
you may want to provide a custom ISerializationBinder
for security reasons. See TypeNameHandling caution in Newtonsoft Json for why.
Upvotes: 13