Update initialDepth for error handling (#1550)

* Fix target depth when skipping over handled errors

Keep reading until the reader reaches the initial depth rather than initial depth + 1

* Fix the initialDepth when handling errors in lists

The initialDepth should be +1 when handling deserialization errors in lists and arrays in order to not skip subsequent items

* Add unit tests for dictionary error handling

Ignoring errors in dictionary object by completely removing the bad items from the dictionary
This commit is contained in:
gilad61
2017-12-26 08:47:41 +13:00
committed by James Newton-King
parent 69640e88d8
commit e5e901c6d0
2 changed files with 33 additions and 6 deletions
@@ -1026,6 +1026,21 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual("Could not convert string to DateTime: 200NOTDATE. Path 'dateTime1', line 7, position 27.", errorMessages[2]);
}
[Test]
public void HandleErrorInDictionaryObject()
{
var json = @"{
model1: { String1: 's1', Int1: 'x' },
model2: { String1: 's2', Int1: 2 }
}";
var dictionary = JsonConvert.DeserializeObject<TolerantDictionary<string, DataModel>>(json);
Assert.AreEqual(1, dictionary.Count);
Assert.IsTrue(dictionary.ContainsKey("model2"));
Assert.AreEqual("s2", dictionary["model2"].String1);
Assert.AreEqual(2, dictionary["model2"].Int1);
}
private class DataModel
{
public string String1 { get; set; }
@@ -1133,4 +1148,16 @@ namespace Newtonsoft.Json.Tests.Serialization
{
}
}
}
/// <summary>
/// A dictionary that ignores deserialization errors and excludes bad items
/// </summary>
public class TolerantDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
[OnError]
public void OnDeserializationError(StreamingContext streamingContext, ErrorContext errorContext)
{
errorContext.Handled = true;
}
}
}
@@ -1474,7 +1474,7 @@ namespace Newtonsoft.Json.Serialization
if (IsErrorHandled(list, contract, errorPosition.Position, reader as IJsonLineInfo, reader.Path, ex))
{
HandleError(reader, true, initialDepth);
HandleError(reader, true, initialDepth + 1);
if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position)
{
@@ -1628,7 +1628,7 @@ namespace Newtonsoft.Json.Serialization
if (IsErrorHandled(underlyingList, contract, errorPosition.Position, reader as IJsonLineInfo, reader.Path, ex))
{
HandleError(reader, true, initialDepth);
HandleError(reader, true, initialDepth + 1);
if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position)
{
@@ -2338,7 +2338,7 @@ namespace Newtonsoft.Json.Serialization
{
if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex))
{
HandleError(reader, true, initialDepth - 1);
HandleError(reader, true, initialDepth);
}
else
{
@@ -2535,7 +2535,7 @@ namespace Newtonsoft.Json.Serialization
{
reader.Skip();
while (reader.Depth > (initialDepth + 1))
while (reader.Depth > initialDepth)
{
if (!reader.Read())
{
@@ -2545,4 +2545,4 @@ namespace Newtonsoft.Json.Serialization
}
}
}
}
}