-Fixed JTokenWriter sometimes losing types when writing JToken

This commit is contained in:
James Newton-King
2016-04-29 16:21:41 +12:00
parent 81098652b3
commit 86c2f80311
6 changed files with 167 additions and 9 deletions
@@ -249,6 +249,100 @@ namespace Newtonsoft.Json.Tests.Linq
]", writer.Token.ToString());
}
[Test]
public void WriteTokenWithParent()
{
JObject o = new JObject
{
["prop1"] = new JArray(1),
["prop2"] = 1
};
JTokenWriter writer = new JTokenWriter();
writer.WriteStartArray();
writer.WriteToken(o.CreateReader());
Assert.AreEqual(WriteState.Array, writer.WriteState);
writer.WriteEndArray();
Console.WriteLine(writer.Token.ToString());
StringAssert.AreEqual(@"[
{
""prop1"": [
1
],
""prop2"": 1
}
]", writer.Token.ToString());
}
[Test]
public void WriteTokenWithPropertyParent()
{
JValue v = new JValue(1);
JTokenWriter writer = new JTokenWriter();
writer.WriteStartObject();
writer.WritePropertyName("Prop1");
writer.WriteToken(v.CreateReader());
Assert.AreEqual(WriteState.Object, writer.WriteState);
writer.WriteEndObject();
StringAssert.AreEqual(@"{
""Prop1"": 1
}", writer.Token.ToString());
}
[Test]
public void WriteValueTokenWithParent()
{
JValue v = new JValue(1);
JTokenWriter writer = new JTokenWriter();
writer.WriteStartArray();
writer.WriteToken(v.CreateReader());
Assert.AreEqual(WriteState.Array, writer.WriteState);
writer.WriteEndArray();
StringAssert.AreEqual(@"[
1
]", writer.Token.ToString());
}
[Test]
public void WriteEmptyToken()
{
JObject o = new JObject();
JsonReader reader = o.CreateReader();
while (reader.Read())
{
}
JTokenWriter writer = new JTokenWriter();
writer.WriteStartArray();
writer.WriteToken(reader);
Assert.AreEqual(WriteState.Array, writer.WriteState);
writer.WriteEndArray();
StringAssert.AreEqual(@"[]", writer.Token.ToString());
}
[Test]
public void WriteRawValue()
{
@@ -55,6 +55,19 @@ namespace Newtonsoft.Json.Tests.Linq
[TestFixture]
public class LinqToJsonTest : TestFixtureBase
{
[Test]
public void ToObject_Guid()
{
JObject anon = new JObject
{
["id"] = Guid.NewGuid()
};
Assert.AreEqual(JTokenType.Guid, anon["id"].Type);
Dictionary<string, JToken> dict = anon.ToObject<Dictionary<string, JToken>>();
Assert.AreEqual(JTokenType.Guid, dict["id"].Type);
}
public class TestClass_ULong
{
public ulong Value { get; set; }
@@ -558,7 +558,7 @@ namespace Newtonsoft.Json.Tests.Serialization
{
ItemWithJTokens actual = (ItemWithJTokens)JsonConvert.DeserializeObject(@"{
""Payload1"": 1,
""Payload2"": {},
""Payload2"": {'prop1':1,'prop2':[2]},
""Payload3"": [1],
""$type"": ""Newtonsoft.Json.Tests.Serialization.MetadataPropertyHandlingTests+ItemWithJTokens, Newtonsoft.Json.Tests""
}",
@@ -568,8 +568,16 @@ namespace Newtonsoft.Json.Tests.Serialization
TypeNameHandling = TypeNameHandling.All
});
Assert.AreEqual(JTokenType.Integer, actual.Payload1.Type);
Assert.AreEqual(1, (int)actual.Payload1);
Assert.AreEqual(null, actual.Payload1.Parent);
Assert.AreEqual(JTokenType.Object, actual.Payload2.Type);
Assert.AreEqual(1, (int)actual.Payload2["prop1"]);
Assert.AreEqual(2, (int)actual.Payload2["prop2"][0]);
Assert.AreEqual(null, actual.Payload2.Parent);
Assert.AreEqual(1, (int)actual.Payload3[0]);
Assert.AreEqual(null, actual.Payload3.Parent);
}
+2 -7
View File
@@ -626,7 +626,7 @@ namespace Newtonsoft.Json
WriteToken(token, null);
}
internal void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
internal virtual void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
{
int initialDepth;
@@ -643,11 +643,6 @@ namespace Newtonsoft.Json
initialDepth = reader.Depth;
}
WriteToken(reader, initialDepth, writeChildren, writeDateConstructorAsDate, writeComments);
}
internal void WriteToken(JsonReader reader, int initialDepth, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
{
do
{
// write a JValue date when the constructor is for a date
@@ -657,7 +652,7 @@ namespace Newtonsoft.Json
}
else
{
if (reader.TokenType != JsonToken.Comment || writeComments)
if (writeComments || reader.TokenType != JsonToken.Comment)
{
WriteToken(reader.TokenType, reader.Value);
}
+46
View File
@@ -485,5 +485,51 @@ namespace Newtonsoft.Json.Linq
AddValue(value, JsonToken.String);
}
#endregion
internal override void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate, bool writeComments)
{
JTokenReader tokenReader = reader as JTokenReader;
if (tokenReader != null && writeChildren && writeDateConstructorAsDate && writeComments)
{
if (tokenReader.TokenType == JsonToken.None)
{
if (!tokenReader.Read())
{
return;
}
}
JToken value = tokenReader.CurrentToken.CloneToken();
if (_parent != null)
{
_parent.Add(value);
_current = _parent.Last;
// if the writer was in a property then move out of it and up to its parent object
if (_parent.Type == JTokenType.Property)
{
_parent = _parent.Parent;
InternalWriteValue(JsonToken.Null);
}
}
else
{
_current = value;
if (_token == null && _value == null)
{
_token = value as JContainer;
_value = value as JValue;
}
}
tokenReader.Skip();
}
else
{
base.WriteToken(reader, writeChildren, writeDateConstructorAsDate, writeComments);
}
}
}
}
@@ -769,9 +769,11 @@ namespace Newtonsoft.Json.Utilities
Attribute[] attributes = a.Cast<Attribute>().ToArray();
#if (NET20 || NET35)
// ye olde .NET GetCustomAttributes doesn't respect the inherit argument
// ye olde .NET GetCustomAttributes doesn't respect the inherit argument
if (inherit && t.BaseType != null)
{
attributes = attributes.Union(GetAttributes(t.BaseType, attributeType, inherit)).ToArray();
}
#endif
return attributes;