-Added GetValue and TryGetValue with StringComparison to JObject
-Fixed SecAnnotate warnings -Fixed error when comparing empty JObjects -Fixed error when comparing DateTime JValue with a DateTimeOffset JValue
This commit is contained in:
@@ -2533,24 +2533,51 @@ bye", reader.Value);
|
||||
//Assert.IsFalse(jsonTextReader.Read());
|
||||
}
|
||||
|
||||
public class ToggleReaderError : TextReader
|
||||
[Test]
|
||||
public void WriteReadBoundaryDecimals()
|
||||
{
|
||||
private readonly TextReader _inner;
|
||||
StringWriter sw = new StringWriter();
|
||||
JsonTextWriter writer = new JsonTextWriter(sw);
|
||||
|
||||
public bool Error { get; set; }
|
||||
writer.WriteStartArray();
|
||||
writer.WriteValue(decimal.MaxValue);
|
||||
writer.WriteValue(decimal.MinValue);
|
||||
writer.WriteEndArray();
|
||||
|
||||
public ToggleReaderError(TextReader inner)
|
||||
{
|
||||
_inner = inner;
|
||||
}
|
||||
string json = sw.ToString();
|
||||
|
||||
public override int Read(char[] buffer, int index, int count)
|
||||
{
|
||||
if (Error)
|
||||
throw new Exception("Read error");
|
||||
StringReader sr = new StringReader(json);
|
||||
JsonTextReader reader = new JsonTextReader(sr);
|
||||
|
||||
return _inner.Read(buffer, index, 1);
|
||||
}
|
||||
Assert.IsTrue(reader.Read());
|
||||
|
||||
decimal? max = reader.ReadAsDecimal();
|
||||
Assert.AreEqual(decimal.MaxValue, max);
|
||||
|
||||
decimal? min = reader.ReadAsDecimal();
|
||||
Assert.AreEqual(decimal.MinValue, min);
|
||||
|
||||
Assert.IsTrue(reader.Read());
|
||||
}
|
||||
}
|
||||
|
||||
public class ToggleReaderError : TextReader
|
||||
{
|
||||
private readonly TextReader _inner;
|
||||
|
||||
public bool Error { get; set; }
|
||||
|
||||
public ToggleReaderError(TextReader inner)
|
||||
{
|
||||
_inner = inner;
|
||||
}
|
||||
|
||||
public override int Read(char[] buffer, int index, int count)
|
||||
{
|
||||
if (Error)
|
||||
throw new Exception("Read error");
|
||||
|
||||
return _inner.Read(buffer, index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1865,5 +1865,52 @@ Parameter name: arrayIndex",
|
||||
l2 = o.ToList<KeyValuePair<string, JToken>>();
|
||||
Assert.AreEqual(1, l2.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EmptyObjectDeepEquals()
|
||||
{
|
||||
Assert.IsTrue(JToken.DeepEquals(new JObject(), new JObject()));
|
||||
|
||||
JObject a = new JObject();
|
||||
JObject b = new JObject();
|
||||
|
||||
b.Add("hi", "bye");
|
||||
b.Remove("hi");
|
||||
|
||||
Assert.IsTrue(JToken.DeepEquals(a, b));
|
||||
Assert.IsTrue(JToken.DeepEquals(b, a));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetValue()
|
||||
{
|
||||
JObject a = new JObject();
|
||||
a["Name"] = "Name!";
|
||||
a["name"] = "name!";
|
||||
a["title"] = "Title!";
|
||||
|
||||
Assert.AreEqual(null, a.GetValue("NAME", StringComparison.Ordinal));
|
||||
Assert.AreEqual(null, a.GetValue("NAME"));
|
||||
Assert.AreEqual(null, a.GetValue("TITLE"));
|
||||
Assert.AreEqual("Name!", (string)a.GetValue("NAME", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.AreEqual("name!", (string)a.GetValue("name", StringComparison.Ordinal));
|
||||
Assert.AreEqual(null, a.GetValue(null, StringComparison.Ordinal));
|
||||
Assert.AreEqual(null, a.GetValue(null));
|
||||
|
||||
JToken v;
|
||||
Assert.IsFalse(a.TryGetValue("NAME", StringComparison.Ordinal, out v));
|
||||
Assert.AreEqual(null, v);
|
||||
|
||||
Assert.IsFalse(a.TryGetValue("NAME", out v));
|
||||
Assert.IsFalse(a.TryGetValue("TITLE", out v));
|
||||
|
||||
Assert.IsTrue(a.TryGetValue("NAME", StringComparison.OrdinalIgnoreCase, out v));
|
||||
Assert.AreEqual("Name!", (string)v);
|
||||
|
||||
Assert.IsTrue(a.TryGetValue("name", StringComparison.Ordinal, out v));
|
||||
Assert.AreEqual("name!", (string)v);
|
||||
|
||||
Assert.IsFalse(a.TryGetValue(null, StringComparison.Ordinal, out v));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(null, v.Value);
|
||||
Assert.AreEqual(JTokenType.Null, v.Type);
|
||||
|
||||
v.Value = (int?)null;
|
||||
v.Value = (int?) null;
|
||||
Assert.AreEqual(null, v.Value);
|
||||
Assert.AreEqual(JTokenType.Null, v.Type);
|
||||
|
||||
@@ -156,11 +156,11 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
public void Last()
|
||||
{
|
||||
ExceptionAssert.Throws<InvalidOperationException>("Cannot access child value on Newtonsoft.Json.Linq.JValue.",
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
JToken last = v.Last;
|
||||
});
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
JToken last = v.Last;
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -175,44 +175,44 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
public void First()
|
||||
{
|
||||
ExceptionAssert.Throws<InvalidOperationException>("Cannot access child value on Newtonsoft.Json.Linq.JValue.",
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
JToken first = v.First;
|
||||
});
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
JToken first = v.First;
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Item()
|
||||
{
|
||||
ExceptionAssert.Throws<InvalidOperationException>("Cannot access child value on Newtonsoft.Json.Linq.JValue.",
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
JToken first = v[0];
|
||||
});
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
JToken first = v[0];
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Values()
|
||||
{
|
||||
ExceptionAssert.Throws<InvalidOperationException>("Cannot access child value on Newtonsoft.Json.Linq.JValue.",
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
v.Values<int>();
|
||||
});
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
v.Values<int>();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveParentNull()
|
||||
{
|
||||
ExceptionAssert.Throws<InvalidOperationException>("The parent is missing.",
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
v.Remove();
|
||||
});
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue(true);
|
||||
v.Remove();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -241,7 +241,7 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
{
|
||||
Assert.IsTrue(JToken.DeepEquals(new JValue(5L), new JValue(5)));
|
||||
Assert.IsFalse(JToken.DeepEquals(new JValue(5M), new JValue(5)));
|
||||
Assert.IsTrue(JToken.DeepEquals(new JValue((ulong)long.MaxValue), new JValue(long.MaxValue)));
|
||||
Assert.IsTrue(JToken.DeepEquals(new JValue((ulong) long.MaxValue), new JValue(long.MaxValue)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -254,22 +254,22 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
public void SetValue()
|
||||
{
|
||||
ExceptionAssert.Throws<InvalidOperationException>("Cannot set child value on Newtonsoft.Json.Linq.JValue.",
|
||||
() =>
|
||||
{
|
||||
JToken t = new JValue(5L);
|
||||
t[0] = new JValue(3);
|
||||
});
|
||||
() =>
|
||||
{
|
||||
JToken t = new JValue(5L);
|
||||
t[0] = new JValue(3);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CastNullValueToNonNullable()
|
||||
{
|
||||
ExceptionAssert.Throws<ArgumentException>("Can not convert Null to Int32.",
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue((object)null);
|
||||
int i = (int)v;
|
||||
});
|
||||
() =>
|
||||
{
|
||||
JValue v = new JValue((object) null);
|
||||
int i = (int) v;
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -320,7 +320,7 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
public decimal Compoundings { get; set; }
|
||||
}
|
||||
|
||||
private readonly Rate rate = new Rate { Compoundings = 12.166666666666666666666666667m };
|
||||
private readonly Rate rate = new Rate {Compoundings = 12.166666666666666666666666667m};
|
||||
|
||||
[Test]
|
||||
public void WriteFullDecimalPrecision()
|
||||
@@ -342,5 +342,26 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
|
||||
Assert.AreEqual(rate.Compoundings, rate2.Compoundings);
|
||||
}
|
||||
|
||||
#if !NET20
|
||||
public class ObjectWithDateTimeOffset
|
||||
{
|
||||
public DateTimeOffset DateTimeOffset { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetDateTimeOffsetProperty()
|
||||
{
|
||||
var dateTimeOffset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(3));
|
||||
var json = JsonConvert.SerializeObject(
|
||||
new ObjectWithDateTimeOffset
|
||||
{
|
||||
DateTimeOffset = dateTimeOffset
|
||||
});
|
||||
|
||||
var o = JObject.Parse(json);
|
||||
o.Property("DateTimeOffset").Value = dateTimeOffset;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -76,5 +76,5 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.5.9.15307")]
|
||||
[assembly: AssemblyFileVersion("4.5.9.15313")]
|
||||
#endif
|
||||
|
||||
@@ -378,6 +378,59 @@ namespace Newtonsoft.Json.Linq
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.
|
||||
/// </summary>
|
||||
/// <value>The <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.</value>
|
||||
public JToken GetValue(string propertyName)
|
||||
{
|
||||
return GetValue(propertyName, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.
|
||||
/// The exact property name will be searched for first and if no matching property is found then
|
||||
/// the <see cref="StringComparison"/> will be used to match a property.
|
||||
/// </summary>
|
||||
/// <value>The <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.</value>
|
||||
public JToken GetValue(string propertyName, StringComparison comparison)
|
||||
{
|
||||
if (propertyName == null)
|
||||
return null;
|
||||
|
||||
// attempt to get value via dictionary first for performance
|
||||
JProperty property = Property(propertyName);
|
||||
if (property != null)
|
||||
return property.Value;
|
||||
|
||||
// test above already uses this comparison so no need to repeat
|
||||
if (comparison != StringComparison.Ordinal)
|
||||
{
|
||||
foreach (JProperty p in _properties)
|
||||
{
|
||||
if (string.Equals(p.Name, propertyName, comparison))
|
||||
return p.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the <see cref="Newtonsoft.Json.Linq.JToken"/> with the specified property name.
|
||||
/// The exact property name will be searched for first and if no matching property is found then
|
||||
/// the <see cref="StringComparison"/> will be used to match a property.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="comparison">One of the enumeration values that specifies how the strings will be compared.</param>
|
||||
/// <returns>true if a value was successfully retrieved; otherwise, false.</returns>
|
||||
public bool TryGetValue(string propertyName, StringComparison comparison, out JToken value)
|
||||
{
|
||||
value = GetValue(propertyName, comparison);
|
||||
return (value != null);
|
||||
}
|
||||
|
||||
#region IDictionary<string,JToken> Members
|
||||
/// <summary>
|
||||
/// Adds the specified property name.
|
||||
|
||||
@@ -200,6 +200,15 @@ namespace Newtonsoft.Json.Linq
|
||||
Dictionary<string, JToken> d1 = _dictionary;
|
||||
Dictionary<string, JToken> d2 = other._dictionary;
|
||||
|
||||
if (d1 == null && d2 == null)
|
||||
return true;
|
||||
|
||||
if (d1 == null)
|
||||
return (d2.Count == 0);
|
||||
|
||||
if (d2 == null)
|
||||
return (d1.Count == 0);
|
||||
|
||||
if (d1.Count != d2.Count)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -216,19 +216,26 @@ namespace Newtonsoft.Json.Linq
|
||||
if (objA is DateTime)
|
||||
{
|
||||
#endif
|
||||
DateTime date1 = Convert.ToDateTime(objA, CultureInfo.InvariantCulture);
|
||||
DateTime date2 = Convert.ToDateTime(objB, CultureInfo.InvariantCulture);
|
||||
DateTime date1 = (DateTime)objA;
|
||||
DateTime date2;
|
||||
|
||||
if (objB is DateTimeOffset)
|
||||
date2 = ((DateTimeOffset)objB).DateTime;
|
||||
else
|
||||
date2 = Convert.ToDateTime(objB, CultureInfo.InvariantCulture);
|
||||
|
||||
return date1.CompareTo(date2);
|
||||
#if !NET20
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(objB is DateTimeOffset))
|
||||
throw new ArgumentException("Object must be of type DateTimeOffset.");
|
||||
|
||||
DateTimeOffset date1 = (DateTimeOffset) objA;
|
||||
DateTimeOffset date2 = (DateTimeOffset) objB;
|
||||
DateTimeOffset date2;
|
||||
|
||||
if (objB is DateTimeOffset)
|
||||
date2 = (DateTimeOffset)objB;
|
||||
else
|
||||
date2 = new DateTimeOffset(Convert.ToDateTime(objB, CultureInfo.InvariantCulture));
|
||||
|
||||
return date1.CompareTo(date2);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.5.0.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.5.9.15307")]
|
||||
[assembly: AssemblyFileVersion("4.5.9.15313")]
|
||||
#endif
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
@@ -27,6 +27,7 @@ using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
#if !(NETFX_CORE || PORTABLE)
|
||||
using System.Security.Permissions;
|
||||
#endif
|
||||
@@ -388,6 +389,9 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
public static bool DynamicCodeGeneration
|
||||
{
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || NETFX_CORE || PORTABLE)
|
||||
[SecuritySafeCritical]
|
||||
#endif
|
||||
get
|
||||
{
|
||||
if (_dynamicCodeGeneration == null)
|
||||
|
||||
Reference in New Issue
Block a user