-Fixed various multidimensional array bugs
This commit is contained in:
@@ -72,5 +72,5 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.5.8.15131")]
|
||||
[assembly: AssemblyFileVersion("4.5.8.15201")]
|
||||
#endif
|
||||
|
||||
@@ -6656,6 +6656,141 @@ Parameter name: value",
|
||||
Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeArray3DWithConverter()
|
||||
{
|
||||
Array3DWithConverter aa = new Array3DWithConverter();
|
||||
aa.Before = "Before!";
|
||||
aa.After = "After!";
|
||||
aa.Coordinates = new[, ,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } };
|
||||
|
||||
string json = JsonConvert.SerializeObject(aa, Formatting.Indented);
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""Before"": ""Before!"",
|
||||
""Coordinates"": [
|
||||
[
|
||||
[
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
1.0,
|
||||
1.0,
|
||||
2.0
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
1.0,
|
||||
2.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
1.0,
|
||||
2.0,
|
||||
2.0
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
2.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
2.0,
|
||||
1.0,
|
||||
2.0
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
2.0,
|
||||
2.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
2.0,
|
||||
2.0,
|
||||
2.0
|
||||
]
|
||||
]
|
||||
],
|
||||
""After"": ""After!""
|
||||
}", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeArray3DWithConverter()
|
||||
{
|
||||
string json = @"{
|
||||
""Before"": ""Before!"",
|
||||
""Coordinates"": [
|
||||
[
|
||||
[
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
1.0,
|
||||
1.0,
|
||||
2.0
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
1.0,
|
||||
2.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
1.0,
|
||||
2.0,
|
||||
2.0
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
2.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
2.0,
|
||||
1.0,
|
||||
2.0
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
2.0,
|
||||
2.0,
|
||||
1.0
|
||||
],
|
||||
[
|
||||
2.0,
|
||||
2.0,
|
||||
2.0
|
||||
]
|
||||
]
|
||||
],
|
||||
""After"": ""After!""
|
||||
}";
|
||||
|
||||
Array3DWithConverter aa = JsonConvert.DeserializeObject<Array3DWithConverter>(json);
|
||||
|
||||
Assert.AreEqual("Before!", aa.Before);
|
||||
Assert.AreEqual("After!", aa.After);
|
||||
Assert.AreEqual(4, aa.Coordinates.GetLength(0));
|
||||
Assert.AreEqual(2, aa.Coordinates.GetLength(1));
|
||||
Assert.AreEqual(3, aa.Coordinates.GetLength(2));
|
||||
Assert.AreEqual(1, aa.Coordinates[0, 0, 0]);
|
||||
Assert.AreEqual(2, aa.Coordinates[1, 1, 1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeArray2D()
|
||||
{
|
||||
@@ -6776,6 +6911,26 @@ Parameter name: value",
|
||||
Assert.AreEqual(json, after);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeIncomplete3DArray()
|
||||
{
|
||||
string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/[1/*hi*/,/*hi*/1/*hi*/,1]/*hi*/,/*hi*/[1,1";
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(
|
||||
"Unexpected end when deserializing array. Path 'Coordinates[0][1][1]', line 1, position 90.",
|
||||
() => JsonConvert.DeserializeObject<Array3D>(json));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeIncompleteNotTopLevel3DArray()
|
||||
{
|
||||
string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/";
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(
|
||||
"Unexpected end when deserializing array. Path 'Coordinates[0]', line 1, position 48.",
|
||||
() => JsonConvert.DeserializeObject<Array3D>(json));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeNull3DArray()
|
||||
{
|
||||
@@ -6809,6 +6964,161 @@ Parameter name: value",
|
||||
|
||||
Assert.AreEqual(json, after);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeReferenceTracked3DArray()
|
||||
{
|
||||
Event e1 = new Event
|
||||
{
|
||||
EventName = "EventName!"
|
||||
};
|
||||
Event[,] array1 = new [,] { { e1, e1 }, { e1, e1 } };
|
||||
IList<Event[,]> values1 = new List<Event[,]>
|
||||
{
|
||||
array1,
|
||||
array1
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings
|
||||
{
|
||||
PreserveReferencesHandling = PreserveReferencesHandling.All,
|
||||
Formatting = Formatting.Indented
|
||||
});
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""$id"": ""1"",
|
||||
""$values"": [
|
||||
{
|
||||
""$id"": ""2"",
|
||||
""$values"": [
|
||||
[
|
||||
{
|
||||
""$id"": ""3"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
},
|
||||
{
|
||||
""$ref"": ""3""
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
""$ref"": ""3""
|
||||
},
|
||||
{
|
||||
""$ref"": ""3""
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
""$ref"": ""2""
|
||||
}
|
||||
]
|
||||
}", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeTypeName3DArray()
|
||||
{
|
||||
Event e1 = new Event
|
||||
{
|
||||
EventName = "EventName!"
|
||||
};
|
||||
Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } };
|
||||
IList<Event[,]> values1 = new List<Event[,]>
|
||||
{
|
||||
array1,
|
||||
array1
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.All,
|
||||
Formatting = Formatting.Indented
|
||||
});
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests]], mscorlib"",
|
||||
""$values"": [
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests"",
|
||||
""$values"": [
|
||||
[
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
},
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
},
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests"",
|
||||
""$values"": [
|
||||
[
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
},
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
},
|
||||
{
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
|
||||
""EventName"": ""EventName!"",
|
||||
""Venue"": null,
|
||||
""Performances"": null
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}", json);
|
||||
|
||||
IList<Event[,]> values2 = (IList<Event[,]>)JsonConvert.DeserializeObject(json, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.All
|
||||
});
|
||||
|
||||
Assert.AreEqual(2, values2.Count);
|
||||
Assert.AreEqual("EventName!", values2[0][0, 0].EventName);
|
||||
}
|
||||
}
|
||||
|
||||
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
|
||||
@@ -7133,4 +7443,30 @@ Parameter name: value",
|
||||
public int[,,] Coordinates { get; set; }
|
||||
public string After { get; set; }
|
||||
}
|
||||
|
||||
public class Array3DWithConverter
|
||||
{
|
||||
public string Before { get; set; }
|
||||
[JsonProperty(ItemConverterType = typeof(IntToFloatConverter))]
|
||||
public int[, ,] Coordinates { get; set; }
|
||||
public string After { get; set; }
|
||||
}
|
||||
|
||||
public class IntToFloatConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteValue(Convert.ToDouble(value));
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
return Convert.ToInt32(reader.Value);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof (int);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,6 +97,99 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.AreEqual("Handle this!", c[2].ThrowError);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializingErrorIn3DArray()
|
||||
{
|
||||
ListErrorObject[,,] c = new ListErrorObject[,,]
|
||||
{
|
||||
{
|
||||
{
|
||||
new ListErrorObject
|
||||
{
|
||||
Member = "Value1",
|
||||
ThrowError = "Handle this!",
|
||||
Member2 = "Member1"
|
||||
},
|
||||
new ListErrorObject
|
||||
{
|
||||
Member = "Value2",
|
||||
Member2 = "Member2"
|
||||
},
|
||||
new ListErrorObject
|
||||
{
|
||||
Member = "Value3",
|
||||
ThrowError = "Handle that!",
|
||||
Member2 = "Member3"
|
||||
}
|
||||
},
|
||||
{
|
||||
new ListErrorObject
|
||||
{
|
||||
Member = "Value1",
|
||||
ThrowError = "Handle this!",
|
||||
Member2 = "Member1"
|
||||
},
|
||||
new ListErrorObject
|
||||
{
|
||||
Member = "Value2",
|
||||
Member2 = "Member2"
|
||||
},
|
||||
new ListErrorObject
|
||||
{
|
||||
Member = "Value3",
|
||||
ThrowError = "Handle that!",
|
||||
Member2 = "Member3"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
Error = (s, e) =>
|
||||
{
|
||||
if (e.CurrentObject.GetType().IsArray)
|
||||
e.ErrorContext.Handled = true;
|
||||
}
|
||||
});
|
||||
|
||||
Assert.AreEqual(@"[
|
||||
[
|
||||
[
|
||||
{
|
||||
""Member"": ""Value1"",
|
||||
""ThrowError"": ""Handle this!"",
|
||||
""Member2"": ""Member1""
|
||||
},
|
||||
{
|
||||
""Member"": ""Value2""
|
||||
},
|
||||
{
|
||||
""Member"": ""Value3"",
|
||||
""ThrowError"": ""Handle that!"",
|
||||
""Member2"": ""Member3""
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
""Member"": ""Value1"",
|
||||
""ThrowError"": ""Handle this!"",
|
||||
""Member2"": ""Member1""
|
||||
},
|
||||
{
|
||||
""Member"": ""Value2""
|
||||
},
|
||||
{
|
||||
""Member"": ""Value3"",
|
||||
""ThrowError"": ""Handle that!"",
|
||||
""Member2"": ""Member3""
|
||||
}
|
||||
]
|
||||
]
|
||||
]", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializingErrorInChildObject()
|
||||
{
|
||||
@@ -339,6 +432,27 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.AreEqual("[1] - 1 - Could not convert string to integer: b. Path '[1]', line 1, position 8.", errors[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HandlingMultidimensionalArrayErrors()
|
||||
{
|
||||
string json = "[[\"a\",\"45\"],[\"b\",34]]";
|
||||
|
||||
List<string> errors = new List<string>();
|
||||
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
serializer.Error += delegate(object sender, ErrorEventArgs args)
|
||||
{
|
||||
errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message);
|
||||
args.ErrorContext.Handled = true;
|
||||
};
|
||||
|
||||
serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof(int[,]));
|
||||
|
||||
Assert.AreEqual(2, errors.Count);
|
||||
Assert.AreEqual("[0][0] - 0 - Could not convert string to integer: a. Path '[0][0]', line 1, position 5.", errors[0]);
|
||||
Assert.AreEqual("[1][0] - 0 - Could not convert string to integer: b. Path '[1][0]', line 1, position 16.", errors[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ErrorHandlingAndAvoidingRecursiveDepthError()
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.5.8.15131")]
|
||||
[assembly: AssemblyFileVersion("4.5.8.15201")]
|
||||
#endif
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
@@ -872,8 +872,6 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
|
||||
contract.InvokeOnDeserializing(list, Serializer.Context);
|
||||
|
||||
int initialDepth = reader.Depth;
|
||||
|
||||
JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType);
|
||||
JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty);
|
||||
|
||||
@@ -884,6 +882,8 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
|
||||
while (true)
|
||||
{
|
||||
int initialDepth = reader.Depth;
|
||||
|
||||
if (listStack.Count == rank)
|
||||
{
|
||||
try
|
||||
@@ -895,6 +895,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
|
||||
case JsonToken.EndArray:
|
||||
listStack.Pop();
|
||||
currentList = listStack.Peek();
|
||||
previousErrorIndex = null;
|
||||
break;
|
||||
case JsonToken.Comment:
|
||||
break;
|
||||
|
||||
@@ -540,7 +540,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
try
|
||||
{
|
||||
JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(values);
|
||||
JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);
|
||||
|
||||
if (ShouldWriteReference(value, null, valueContract, contract, member))
|
||||
{
|
||||
@@ -557,7 +557,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (IsErrorHandled(values, contract, i, writer.ContainerPath, ex))
|
||||
HandleError(writer, initialDepth);
|
||||
HandleError(writer, initialDepth + 1);
|
||||
else
|
||||
throw;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user