-Fixed serializing root references from JsonConverters

This commit is contained in:
James Newton-King
2015-05-17 22:55:07 +12:00
parent 117475cc9c
commit f4e8c3d2ca
2 changed files with 103 additions and 1 deletions
@@ -47,6 +47,101 @@ namespace Newtonsoft.Json.Tests.Serialization
[TestFixture]
public class PreserveReferencesHandlingTests : TestFixtureBase
{
public class ContentB
{
public bool SomeValue { get; set; }
}
[JsonConverter(typeof(ListConverter))]
public class ContentA : List<object>
{
public ContentB B { get; set; }
public ContentA()
{
B = new ContentB();
}
}
public class ListConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new ContentA() { B = serializer.Deserialize<ContentB>(reader) }; // Construct my data back.
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
ContentB b = ((ContentA)value).B;
serializer.Serialize(writer, b); // My Content.B contains all useful data.
}
}
public class Container
{
public List<ContentA> ListA { get; set; }
public List<ContentA> ListB { get; set; }
public Container()
{
ListA = new List<ContentA>();
ListB = new List<ContentA>();
}
}
[Test]
public void SerializeReferenceInConvert()
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
settings.TypeNameHandling = TypeNameHandling.All;
settings.Formatting = Formatting.Indented;
Container c1 = new Container();
ContentA content = new ContentA();
content.B.SomeValue = true;
c1.ListA.Add(content);
c1.ListB.Add(content);
string s = JsonConvert.SerializeObject(c1, settings);
StringAssert.AreEqual(@"{
""$id"": ""1"",
""$type"": ""Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+Container, Newtonsoft.Json.Tests"",
""ListA"": {
""$id"": ""2"",
""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+ContentA, Newtonsoft.Json.Tests]], mscorlib"",
""$values"": [
{
""$id"": ""3"",
""$type"": ""Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+ContentB, Newtonsoft.Json.Tests"",
""SomeValue"": true
}
]
},
""ListB"": {
""$id"": ""4"",
""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+ContentA, Newtonsoft.Json.Tests]], mscorlib"",
""$values"": [
{
""$ref"": ""3""
}
]
}
}", s);
Container c2 = JsonConvert.DeserializeObject<Container>(s, settings);
Assert.AreEqual(c2.ListA[0], c2.ListB[0]);
Assert.AreEqual(true, c2.ListA[0].B.SomeValue);
}
public class Parent
{
public Child ReadOnlyChild
@@ -70,7 +70,14 @@ namespace Newtonsoft.Json.Serialization
try
{
SerializeValue(jsonWriter, value, contract, null, null, null);
if (ShouldWriteReference(value, null, contract, null, null))
{
WriteReference(jsonWriter, value);
}
else
{
SerializeValue(jsonWriter, value, contract, null, null, null);
}
}
catch (Exception ex)
{