Merge branch 'is-reference-bug' of https://github.com/TylerBrinkley/Newtonsoft.Json into TylerBrinkley-is-reference-bug

This commit is contained in:
James Newton-King
2016-10-25 16:09:36 +13:00
2 changed files with 64 additions and 4 deletions
@@ -656,6 +656,66 @@ namespace Newtonsoft.Json.Tests.Serialization
Assert.AreEqual(employees[0], employees[1].Manager);
}
[JsonObject(IsReference = true)]
private class Condition
{
public int Value { get; }
public Condition(int value)
{
Value = value;
}
}
private class ClassWithConditions
{
public Condition Condition1 { get; }
public Condition Condition2 { get; }
public ClassWithConditions(Condition condition1, Condition condition2)
{
Condition1 = condition1;
Condition2 = condition2;
}
}
[Test]
public void SerializeIsReferenceReadonlyProperty()
{
Condition condition = new Condition(1);
ClassWithConditions value = new ClassWithConditions(condition, condition);
string json = JsonConvert.SerializeObject(value, Formatting.Indented);
StringAssert.AreEqual(@"{
""Condition1"": {
""$id"": ""1"",
""Value"": 1
},
""Condition2"": {
""$ref"": ""1""
}
}", json);
}
[Test]
public void DeserializeIsReferenceReadonlyProperty()
{
string json = @"{
""Condition1"": {
""$id"": ""1"",
""Value"": 1
},
""Condition2"": {
""$ref"": ""1""
}
}";
ClassWithConditions value = JsonConvert.DeserializeObject<ClassWithConditions>(json);
Assert.AreEqual(value.Condition1.Value, 1);
Assert.AreEqual(value.Condition1, value.Condition2);
}
[Test]
public void SerializeCircularReference()
{
@@ -577,8 +577,8 @@ namespace Newtonsoft.Json.Serialization
writer.WriteStartObject();
bool isReference = ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects);
// don't make readonly fields the referenced value because they can't be deserialized to
if (isReference && (member == null || member.Writable))
// don't make readonly fields that aren't creator parameters the referenced value because they can't be deserialized to
if (isReference && (member == null || member.Writable || ((collectionContract as JsonObjectContract)?.CreatorParameters.Contains(member.PropertyName) ?? false)))
{
WriteReferenceIdProperty(writer, contract.UnderlyingType, value);
}
@@ -804,8 +804,8 @@ namespace Newtonsoft.Json.Serialization
private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
{
bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays);
// don't make readonly fields the referenced value because they can't be deserialized to
isReference = (isReference && (member == null || member.Writable));
// don't make readonly fields that aren't creator parameters the referenced value because they can't be deserialized to
isReference = (isReference && (member == null || member.Writable || ((containerContract as JsonObjectContract)?.CreatorParameters.Contains(member.PropertyName) ?? false)));
bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty);
bool writeMetadataObject = isReference || includeTypeDetails;