-Added async serialize/deserialize methods to JsonConvert
-Fixed performance issue when deserializing deeply nested JSON to LINQ to JSON objects
This commit is contained in:
@@ -24,11 +24,18 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
#if !(NET20 || NET35 || SILVERLIGHT)
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Tests.Serialization;
|
||||
using Newtonsoft.Json.Tests.TestObjects;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using NUnit.Framework;
|
||||
|
||||
@@ -640,5 +647,78 @@ now brown cow?", '"', true);
|
||||
|
||||
return (T)converter.ReadJson(reader, typeof(T), null, null);
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35 || SILVERLIGHT)
|
||||
[Test]
|
||||
public void Async()
|
||||
{
|
||||
Task<string> task = null;
|
||||
|
||||
task = JsonConvert.SerializeObjectAsync(42);
|
||||
task.Wait();
|
||||
|
||||
Assert.AreEqual("42", task.Result);
|
||||
|
||||
task = JsonConvert.SerializeObjectAsync(new[] {1, 2, 3, 4, 5}, Formatting.Indented);
|
||||
task.Wait();
|
||||
|
||||
Assert.AreEqual(@"[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5
|
||||
]", task.Result);
|
||||
|
||||
task = JsonConvert.SerializeObjectAsync(DateTime.MaxValue, Formatting.None, new JsonSerializerSettings
|
||||
{
|
||||
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
|
||||
});
|
||||
task.Wait();
|
||||
|
||||
Assert.AreEqual(@"""\/Date(253402300799999)\/""", task.Result);
|
||||
|
||||
var taskObject = JsonConvert.DeserializeObjectAsync("[]");
|
||||
taskObject.Wait();
|
||||
|
||||
Assert.AreEqual(new JArray(), taskObject.Result);
|
||||
|
||||
Task<object> taskVersionArray = JsonConvert.DeserializeObjectAsync("['2.0']", typeof(Version[]), new JsonSerializerSettings
|
||||
{
|
||||
Converters = {new VersionConverter()}
|
||||
});
|
||||
taskVersionArray.Wait();
|
||||
|
||||
Version[] versionArray = (Version[])taskVersionArray.Result;
|
||||
|
||||
Assert.AreEqual(1, versionArray.Length);
|
||||
Assert.AreEqual(2, versionArray[0].Major);
|
||||
|
||||
Task<int> taskInt = JsonConvert.DeserializeObjectAsync<int>("5");
|
||||
taskInt.Wait();
|
||||
|
||||
Assert.AreEqual(5, taskInt.Result);
|
||||
|
||||
var taskVersion = JsonConvert.DeserializeObjectAsync<Version>("'2.0'", new JsonSerializerSettings
|
||||
{
|
||||
Converters = {new VersionConverter()}
|
||||
});
|
||||
taskVersion.Wait();
|
||||
|
||||
Assert.AreEqual(2, taskVersion.Result.Major);
|
||||
|
||||
Movie p = new Movie();
|
||||
p.Name = "Existing,";
|
||||
|
||||
Task taskVoid = JsonConvert.PopulateObjectAsync("{'Name':'Appended'}", p, new JsonSerializerSettings
|
||||
{
|
||||
Converters = new List<JsonConverter> { new JsonSerializerTest.StringAppenderConverter() }
|
||||
});
|
||||
|
||||
taskVoid.Wait();
|
||||
|
||||
Assert.AreEqual("Existing,Appended", p.Name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -704,7 +704,6 @@ namespace Newtonsoft.Json.Tests
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore]
|
||||
public void NestedJToken()
|
||||
{
|
||||
Stopwatch sw;
|
||||
@@ -717,7 +716,7 @@ namespace Newtonsoft.Json.Tests
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
JArray temp = new JArray();
|
||||
ija.Add(temp);
|
||||
ija.AddAndSkipParentCheck(temp);
|
||||
ija = temp;
|
||||
}
|
||||
ija.Add(1);
|
||||
@@ -727,26 +726,21 @@ namespace Newtonsoft.Json.Tests
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore]
|
||||
public void NestedXElement()
|
||||
public void DeserializeNestedJToken()
|
||||
{
|
||||
string json = (new string('[', 100000)) + "1" + ((new string(']', 100000)));
|
||||
|
||||
Stopwatch sw;
|
||||
for (int i = 10000; i <= 100000; i += 10000)
|
||||
{
|
||||
sw = new Stopwatch();
|
||||
sw.Start();
|
||||
XElement ija = new XElement("root");
|
||||
XElement ijt = ija;
|
||||
for (int j = 0; j < i; j++)
|
||||
{
|
||||
XElement temp = new XElement("child");
|
||||
ija.Add(temp);
|
||||
ija = temp;
|
||||
}
|
||||
ija.Add(1);
|
||||
sw.Stop();
|
||||
Console.WriteLine("Created a XElement of depth {0} (using OM) in {1} millis", i, sw.ElapsedMilliseconds);
|
||||
}
|
||||
sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
var a = (JArray)JsonConvert.DeserializeObject(json);
|
||||
|
||||
sw.Stop();
|
||||
|
||||
Assert.AreEqual(1, a.Count);
|
||||
|
||||
Console.WriteLine("Deserialize big ass nested array in {0} millis", sw.ElapsedMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,5 +72,5 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.0.8.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.0.8.14704")]
|
||||
[assembly: AssemblyFileVersion("4.0.8.14707")]
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
#if !(NET20 || NET35 || SILVERLIGHT)
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Converters;
|
||||
@@ -643,6 +646,7 @@ namespace Newtonsoft.Json
|
||||
return IsJsonPrimitiveTypeCode(Type.GetTypeCode(type));
|
||||
}
|
||||
|
||||
#region Serialize
|
||||
/// <summary>
|
||||
/// Serializes the specified object to a JSON string.
|
||||
/// </summary>
|
||||
@@ -733,6 +737,50 @@ namespace Newtonsoft.Json
|
||||
return sw.ToString();
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35 || SILVERLIGHT)
|
||||
/// <summary>
|
||||
/// Asynchronously serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The object to serialize.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous serialize operation. The value of the <c>TResult</c> parameter contains a JSON string representation of the object.
|
||||
/// </returns>
|
||||
public static Task<string> SerializeObjectAsync(object value)
|
||||
{
|
||||
return SerializeObjectAsync(value, Formatting.None, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The object to serialize.</param>
|
||||
/// <param name="formatting">Indicates how the output is formatted.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous serialize operation. The value of the <c>TResult</c> parameter contains a JSON string representation of the object.
|
||||
/// </returns>
|
||||
public static Task<string> SerializeObjectAsync(object value, Formatting formatting)
|
||||
{
|
||||
return SerializeObjectAsync(value, formatting, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously serializes the specified object to a JSON string using a collection of <see cref="JsonConverter"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The object to serialize.</param>
|
||||
/// <param name="formatting">Indicates how the output is formatted.</param>
|
||||
/// <param name="settings">The <see cref="JsonSerializerSettings"/> used to serialize the object.
|
||||
/// If this is null, default serialization settings will be is used.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous serialize operation. The value of the <c>TResult</c> parameter contains a JSON string representation of the object.
|
||||
/// </returns>
|
||||
public static Task<string> SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings)
|
||||
{
|
||||
return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings));
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region Deserialize
|
||||
/// <summary>
|
||||
/// Deserializes the JSON to a .NET object.
|
||||
/// </summary>
|
||||
@@ -868,6 +916,68 @@ namespace Newtonsoft.Json
|
||||
return deserializedValue;
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35 || SILVERLIGHT)
|
||||
/// <summary>
|
||||
/// Asynchronously deserializes the JSON to the specified .NET type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize to.</typeparam>
|
||||
/// <param name="value">The JSON to deserialize.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
|
||||
/// </returns>
|
||||
public static Task<T> DeserializeObjectAsync<T>(string value)
|
||||
{
|
||||
return DeserializeObjectAsync<T>(value, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deserializes the JSON to the specified .NET type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize to.</typeparam>
|
||||
/// <param name="value">The JSON to deserialize.</param>
|
||||
/// <param name="settings">
|
||||
/// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
|
||||
/// If this is null, default serialization settings will be is used.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
|
||||
/// </returns>
|
||||
public static Task<T> DeserializeObjectAsync<T>(string value, JsonSerializerSettings settings)
|
||||
{
|
||||
return Task.Factory.StartNew(() => DeserializeObject<T>(value, settings));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deserializes the JSON to the specified .NET type.
|
||||
/// </summary>
|
||||
/// <param name="value">The JSON to deserialize.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
|
||||
/// </returns>
|
||||
public static Task<object> DeserializeObjectAsync(string value)
|
||||
{
|
||||
return DeserializeObjectAsync(value, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deserializes the JSON to the specified .NET type.
|
||||
/// </summary>
|
||||
/// <param name="value">The JSON to deserialize.</param>
|
||||
/// <param name="type">The type of the object to deserialize to.</param>
|
||||
/// <param name="settings">
|
||||
/// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
|
||||
/// If this is null, default serialization settings will be is used.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous deserialize operation. The value of the <c>TResult</c> parameter contains the deserialized object from the JSON string.
|
||||
/// </returns>
|
||||
public static Task<object> DeserializeObjectAsync(string value, Type type, JsonSerializerSettings settings)
|
||||
{
|
||||
return Task.Factory.StartNew(() => DeserializeObject(value, type, settings));
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Populates the object with values from the JSON string.
|
||||
/// </summary>
|
||||
@@ -878,7 +988,6 @@ namespace Newtonsoft.Json
|
||||
PopulateObject(value, target, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Populates the object with values from the JSON string.
|
||||
/// </summary>
|
||||
@@ -902,6 +1011,25 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35 || SILVERLIGHT)
|
||||
/// <summary>
|
||||
/// Asynchronously populates the object with values from the JSON string.
|
||||
/// </summary>
|
||||
/// <param name="value">The JSON to populate values from.</param>
|
||||
/// <param name="target">The target object to populate values onto.</param>
|
||||
/// <param name="settings">
|
||||
/// The <see cref="JsonSerializerSettings"/> used to deserialize the object.
|
||||
/// If this is null, default serialization settings will be is used.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous populate operation.
|
||||
/// </returns>
|
||||
public static Task PopulateObjectAsync(string value, object target, JsonSerializerSettings settings)
|
||||
{
|
||||
return Task.Factory.StartNew(() => PopulateObject(value, target, settings));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SILVERLIGHT
|
||||
/// <summary>
|
||||
/// Serializes the XML node to a JSON string.
|
||||
|
||||
@@ -159,11 +159,13 @@ namespace Newtonsoft.Json
|
||||
|
||||
private bool ParseDateIso(string text)
|
||||
{
|
||||
const string isoDateFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFK";
|
||||
|
||||
#if !NET20
|
||||
if (_readType == ReadType.ReadAsDateTimeOffset)
|
||||
{
|
||||
DateTimeOffset dateTimeOffset;
|
||||
if (DateTimeOffset.TryParseExact(text, "yyyy-MM-ddTHH:mm:ss.FFFFFFFK", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
|
||||
if (DateTimeOffset.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
|
||||
{
|
||||
SetToken(JsonToken.Date, dateTimeOffset);
|
||||
return true;
|
||||
@@ -173,7 +175,7 @@ namespace Newtonsoft.Json
|
||||
#endif
|
||||
{
|
||||
DateTime dateTime;
|
||||
if (DateTime.TryParseExact(text, "yyyy-MM-ddTHH:mm:ss.FFFFFFFK", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime))
|
||||
if (DateTime.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime))
|
||||
{
|
||||
dateTime = JsonConvert.EnsureDateTime(dateTime, DateTimeZoneHandling);
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ namespace Newtonsoft.Json.Linq
|
||||
/// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
|
||||
public void Insert(int index, JToken item)
|
||||
{
|
||||
InsertItem(index, item);
|
||||
InsertItem(index, item, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -261,7 +261,7 @@ namespace Newtonsoft.Json.Linq
|
||||
return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[]));
|
||||
}
|
||||
|
||||
internal JToken EnsureParentToken(JToken item)
|
||||
internal JToken EnsureParentToken(JToken item, bool skipParentCheck)
|
||||
{
|
||||
if (item == null)
|
||||
return new JValue((object) null);
|
||||
@@ -273,14 +273,18 @@ namespace Newtonsoft.Json.Linq
|
||||
else
|
||||
{
|
||||
// check whether attempting to add a token to itself
|
||||
JContainer parent = this;
|
||||
while (parent.Parent != null)
|
||||
// not possible with a value, only a container
|
||||
if (item is JContainer && !skipParentCheck)
|
||||
{
|
||||
parent = parent.Parent;
|
||||
}
|
||||
if (item == parent)
|
||||
{
|
||||
item = item.CloneToken();
|
||||
JContainer parent = this;
|
||||
while (parent.Parent != null)
|
||||
{
|
||||
parent = parent.Parent;
|
||||
}
|
||||
if (item == parent)
|
||||
{
|
||||
item = item.CloneToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
@@ -309,14 +313,14 @@ namespace Newtonsoft.Json.Linq
|
||||
return ChildrenTokens.IndexOf(item, JTokenReferenceEqualityComparer.Instance);
|
||||
}
|
||||
|
||||
internal virtual void InsertItem(int index, JToken item)
|
||||
internal virtual void InsertItem(int index, JToken item, bool skipParentCheck)
|
||||
{
|
||||
if (index > ChildrenTokens.Count)
|
||||
throw new ArgumentOutOfRangeException("index", "Index must be within the bounds of the List.");
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
item = EnsureParentToken(item);
|
||||
item = EnsureParentToken(item, skipParentCheck);
|
||||
|
||||
JToken previous = (index == 0) ? null : ChildrenTokens[index - 1];
|
||||
// haven't inserted new token yet so next token is still at the inserting index
|
||||
@@ -409,7 +413,7 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
CheckReentrancy();
|
||||
|
||||
item = EnsureParentToken(item);
|
||||
item = EnsureParentToken(item, false);
|
||||
|
||||
ValidateToken(item, existing);
|
||||
|
||||
@@ -523,7 +527,12 @@ namespace Newtonsoft.Json.Linq
|
||||
/// <param name="content">The content to be added.</param>
|
||||
public virtual void Add(object content)
|
||||
{
|
||||
AddInternal(ChildrenTokens.Count, content);
|
||||
AddInternal(ChildrenTokens.Count, content, false);
|
||||
}
|
||||
|
||||
internal void AddAndSkipParentCheck(JToken token)
|
||||
{
|
||||
AddInternal(ChildrenTokens.Count, token, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -532,10 +541,10 @@ namespace Newtonsoft.Json.Linq
|
||||
/// <param name="content">The content to be added.</param>
|
||||
public void AddFirst(object content)
|
||||
{
|
||||
AddInternal(0, content);
|
||||
AddInternal(0, content, false);
|
||||
}
|
||||
|
||||
internal void AddInternal(int index, object content)
|
||||
internal void AddInternal(int index, object content, bool skipParentCheck)
|
||||
{
|
||||
if (IsMultiContent(content))
|
||||
{
|
||||
@@ -544,7 +553,7 @@ namespace Newtonsoft.Json.Linq
|
||||
int multiIndex = index;
|
||||
foreach (object c in enumerable)
|
||||
{
|
||||
AddInternal(multiIndex, c);
|
||||
AddInternal(multiIndex, c, skipParentCheck);
|
||||
multiIndex++;
|
||||
}
|
||||
}
|
||||
@@ -552,7 +561,7 @@ namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
JToken item = CreateFromContent(content);
|
||||
|
||||
InsertItem(index, item);
|
||||
InsertItem(index, item, skipParentCheck);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,7 +754,7 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
void IList<JToken>.Insert(int index, JToken item)
|
||||
{
|
||||
InsertItem(index, item);
|
||||
InsertItem(index, item, false);
|
||||
}
|
||||
|
||||
void IList<JToken>.RemoveAt(int index)
|
||||
@@ -831,7 +840,7 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
void IList.Insert(int index, object value)
|
||||
{
|
||||
InsertItem(index, EnsureValue(value));
|
||||
InsertItem(index, EnsureValue(value), false);
|
||||
}
|
||||
|
||||
bool IList.IsFixedSize
|
||||
|
||||
@@ -146,13 +146,13 @@ namespace Newtonsoft.Json.Linq
|
||||
return (t != null && ContentsEqual(t));
|
||||
}
|
||||
|
||||
internal override void InsertItem(int index, JToken item)
|
||||
internal override void InsertItem(int index, JToken item, bool skipParentCheck)
|
||||
{
|
||||
// don't add comments to JObject, no name to reference comment by
|
||||
if (item != null && item.Type == JTokenType.Comment)
|
||||
return;
|
||||
|
||||
base.InsertItem(index, item);
|
||||
base.InsertItem(index, item, skipParentCheck);
|
||||
}
|
||||
|
||||
internal override void ValidateToken(JToken o, JToken existing)
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Newtonsoft.Json.Linq
|
||||
|
||||
if (ChildrenTokens.Count == 0)
|
||||
{
|
||||
InsertItem(0, newValue);
|
||||
InsertItem(0, newValue, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -132,12 +132,12 @@ namespace Newtonsoft.Json.Linq
|
||||
throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
|
||||
}
|
||||
|
||||
internal override void InsertItem(int index, JToken item)
|
||||
internal override void InsertItem(int index, JToken item, bool skipParentCheck)
|
||||
{
|
||||
if (Value != null)
|
||||
throw new Exception("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
|
||||
|
||||
base.InsertItem(0, item);
|
||||
base.InsertItem(0, item, false);
|
||||
}
|
||||
|
||||
internal override bool ContainsItem(JToken item)
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace Newtonsoft.Json.Linq
|
||||
throw new InvalidOperationException("The parent is missing.");
|
||||
|
||||
int index = _parent.IndexOfItem(this);
|
||||
_parent.AddInternal(index + 1, content);
|
||||
_parent.AddInternal(index + 1, content, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -180,7 +180,7 @@ namespace Newtonsoft.Json.Linq
|
||||
throw new InvalidOperationException("The parent is missing.");
|
||||
|
||||
int index = _parent.IndexOfItem(this);
|
||||
_parent.AddInternal(index, content);
|
||||
_parent.AddInternal(index, content, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Newtonsoft.Json.Linq
|
||||
if (_parent == null)
|
||||
_token = container;
|
||||
else
|
||||
_parent.Add(container);
|
||||
_parent.AddAndSkipParentCheck(container);
|
||||
|
||||
_parent = container;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.0.8.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.0.8.14704")]
|
||||
[assembly: AssemblyFileVersion("4.0.8.14707")]
|
||||
#endif
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
Reference in New Issue
Block a user