-Added IConvertible support to JValue

-Changed IDictionary<DateTime, object> to be serialized in ISO date format
-Fixed DataContractAttribute to not be inherited
This commit is contained in:
James Newton-King
2013-03-11 19:23:23 +13:00
parent 92de187a74
commit aab01d93ca
15 changed files with 760 additions and 160 deletions
@@ -397,5 +397,145 @@ namespace Newtonsoft.Json.Tests.Linq
CustomAssert.IsInstanceOfType(typeof(DateTimeOffset), startDateTime);
}
#endif
[Test]
public void ConvertsToBoolean()
{
Assert.AreEqual(true, Convert.ToBoolean(new JValue(true)));
}
[Test]
public void ConvertsToBoolean_String()
{
Assert.AreEqual(true, Convert.ToBoolean(new JValue("true")));
}
[Test]
public void ConvertsToInt32()
{
Assert.AreEqual(Int32.MaxValue, Convert.ToInt32(new JValue(Int32.MaxValue)));
}
[Test]
public void ConvertsToChar()
{
Assert.AreEqual('c', Convert.ToChar(new JValue('c')));
}
[Test]
public void ConvertsToSByte()
{
Assert.AreEqual(SByte.MaxValue, Convert.ToSByte(new JValue(SByte.MaxValue)));
}
[Test]
public void ConvertsToByte()
{
Assert.AreEqual(Byte.MaxValue, Convert.ToByte(new JValue(Byte.MaxValue)));
}
[Test]
public void ConvertsToInt16()
{
Assert.AreEqual(Int16.MaxValue, Convert.ToInt16(new JValue(Int16.MaxValue)));
}
[Test]
public void ConvertsToUInt16()
{
Assert.AreEqual(UInt16.MaxValue, Convert.ToUInt16(new JValue(UInt16.MaxValue)));
}
[Test]
public void ConvertsToUInt32()
{
Assert.AreEqual(UInt32.MaxValue, Convert.ToUInt32(new JValue(UInt32.MaxValue)));
}
[Test]
public void ConvertsToInt64()
{
Assert.AreEqual(Int64.MaxValue, Convert.ToInt64(new JValue(Int64.MaxValue)));
}
[Test]
public void ConvertsToUInt64()
{
Assert.AreEqual(UInt64.MaxValue, Convert.ToUInt64(new JValue(UInt64.MaxValue)));
}
[Test]
public void ConvertsToSingle()
{
Assert.AreEqual(Single.MaxValue, Convert.ToSingle(new JValue(Single.MaxValue)));
}
[Test]
public void ConvertsToDouble()
{
Assert.AreEqual(Double.MaxValue, Convert.ToDouble(new JValue(Double.MaxValue)));
}
[Test]
public void ConvertsToDecimal()
{
Assert.AreEqual(Decimal.MaxValue, Convert.ToDecimal(new JValue(Decimal.MaxValue)));
}
[Test]
public void ConvertsToString_Decimal()
{
Assert.AreEqual("79228162514264337593543950335", Convert.ToString(new JValue(Decimal.MaxValue)));
}
[Test]
public void ConvertsToString_Uri()
{
Assert.AreEqual("http://www.google.com/", Convert.ToString(new JValue(new Uri("http://www.google.com"))));
}
[Test]
public void ConvertsToString_Null()
{
Assert.AreEqual(string.Empty, Convert.ToString(new JValue((object)null)));
}
[Test]
public void ConvertsToString_Guid()
{
Guid g = new Guid("0B5D4F85-E94C-4143-94C8-35F2AAEBB100");
Assert.AreEqual("0b5d4f85-e94c-4143-94c8-35f2aaebb100", Convert.ToString(new JValue(g)));
}
[Test]
public void ConvertsToType()
{
Assert.AreEqual(Int32.MaxValue, Convert.ChangeType(new JValue(Int32.MaxValue), typeof(Int32), CultureInfo.InvariantCulture));
}
[Test]
public void ConvertsToDateTime()
{
Assert.AreEqual(new DateTime(2013, 02, 01, 01, 02, 03, 04), Convert.ToDateTime(new JValue(new DateTime(2013, 02, 01, 01, 02, 03, 04))));
}
#if !NET20
[Test]
public void ConvertsToDateTime_DateTimeOffset()
{
var offset = new DateTimeOffset(2013, 02, 01, 01, 02, 03, 04, TimeSpan.Zero);
Assert.AreEqual(new DateTime(2013, 02, 01, 01, 02, 03, 04), Convert.ToDateTime(new JValue(offset)));
}
#endif
[Test]
public void GetTypeCode()
{
IConvertible v = new JValue(new Guid("0B5D4F85-E94C-4143-94C8-35F2AAEBB100"));
Assert.AreEqual(TypeCode.Object, v.GetTypeCode());
}
}
}
@@ -57,7 +57,7 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\Net20\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>TRACE;NET20</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
@@ -73,4 +73,4 @@ using System.Security;
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
[assembly: AssemblyFileVersion("4.5.11.15906")]
[assembly: AssemblyFileVersion("4.5.11.15911")]
@@ -4923,6 +4923,25 @@ To fix this error either change the environment to be fully trusted, change the
[Test]
public void ChildDataContractTest()
{
ChildDataContract cc = new ChildDataContract
{
VirtualMember = "VirtualMember!",
NonVirtualMember = "NonVirtualMember!"
};
string result = JsonConvert.SerializeObject(cc, Formatting.Indented);
// Assert.AreEqual(@"{
// ""VirtualMember"": ""VirtualMember!"",
// ""NewMember"": null,
// ""nonVirtualMember"": ""NonVirtualMember!""
//}", result);
Console.WriteLine(result);
}
[Test]
public void ChildDataContractTestWithDataContractSerializer()
{
ChildDataContract cc = new ChildDataContract
{
@@ -4930,8 +4949,14 @@ To fix this error either change the environment to be fully trusted, change the
NonVirtualMember = "NonVirtualMember!"
};
string result = JsonConvert.SerializeObject(cc);
Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
DataContractSerializer serializer = new DataContractSerializer(typeof(ChildDataContract));
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, cc);
string xml = Encoding.UTF8.GetString(ms.ToArray(), 0, Convert.ToInt32(ms.Length));
Console.WriteLine(xml);
}
#endif
@@ -6226,6 +6251,106 @@ Parameter name: value",
Assert.AreEqual(@"{""Data"":["":::ONE:::"","":::TWO:::"","":::THREE:::""]}", json);
}
#if !NET20
[Test]
public void DateTimeDictionaryKey_DateTimeOffset_Iso()
{
IDictionary<DateTimeOffset, int> dic1 = new Dictionary<DateTimeOffset, int>
{
{new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1},
{new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2}
};
string json = JsonConvert.SerializeObject(dic1, Formatting.Indented);
Assert.AreEqual(@"{
""2000-12-12T12:12:12+00:00"": 1,
""2013-12-12T12:12:12+00:00"": 2
}", json);
IDictionary<DateTimeOffset, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTimeOffset, int>>(json);
Assert.AreEqual(2, dic2.Count);
Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
}
[Test]
public void DateTimeDictionaryKey_DateTimeOffset_MS()
{
IDictionary<DateTimeOffset, int> dic1 = new Dictionary<DateTimeOffset, int>
{
{new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1},
{new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2}
};
string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
});
Assert.AreEqual(@"{
""\/Date(976623132000+0000)\/"": 1,
""\/Date(1386850332000+0000)\/"": 2
}", json);
IDictionary<DateTimeOffset, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTimeOffset, int>>(json);
Assert.AreEqual(2, dic2.Count);
Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
}
#endif
[Test]
public void DateTimeDictionaryKey_DateTime_Iso()
{
IDictionary<DateTime, int> dic1 = new Dictionary<DateTime, int>
{
{new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1},
{new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2}
};
string json = JsonConvert.SerializeObject(dic1, Formatting.Indented);
Assert.AreEqual(@"{
""2000-12-12T12:12:12Z"": 1,
""2013-12-12T12:12:12Z"": 2
}", json);
IDictionary<DateTime, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTime, int>>(json);
Assert.AreEqual(2, dic2.Count);
Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
}
[Test]
public void DateTimeDictionaryKey_DateTime_MS()
{
IDictionary<DateTime, int> dic1 = new Dictionary<DateTime, int>
{
{new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1},
{new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2}
};
string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
});
Assert.AreEqual(@"{
""\/Date(976623132000)\/"": 1,
""\/Date(1386850332000)\/"": 2
}", json);
IDictionary<DateTime, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTime, int>>(json);
Assert.AreEqual(2, dic2.Count);
Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
}
[Test]
public void DeserializeEmptyJsonString()
{
@@ -24,10 +24,17 @@
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
#if NET20
using Newtonsoft.Json.Utilities.LinqBridge;
#else
using System.Linq;
#endif
using System.Reflection;
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Tests.TestObjects;
#if !NETFX_CORE
@@ -346,5 +353,170 @@ namespace Newtonsoft.Json.Tests.Serialization
Console.WriteLine("Error has been fixed");
}
}
[Test]
public void DerivedSerializationEvents()
{
var c = JsonConvert.DeserializeObject<DerivedSerializationEventOrderTestObject>("{}");
JsonConvert.SerializeObject(c, Formatting.Indented);
IList<string> e = c.GetEvents();
Assert.AreEqual(@"OnDeserializing
OnDeserializing_Derived
OnDeserialized
OnDeserialized_Derived
OnSerializing
OnSerializing_Derived
OnSerialized
OnSerialized_Derived", string.Join(Environment.NewLine, e.ToArray()));
}
[Test]
public void DerivedDerivedSerializationEvents()
{
var c = JsonConvert.DeserializeObject<DerivedDerivedSerializationEventOrderTestObject>("{}");
JsonConvert.SerializeObject(c, Formatting.Indented);
IList<string> e = c.GetEvents();
Assert.AreEqual(@"OnDeserializing
OnDeserializing_Derived
OnDeserializing_Derived_Derived
OnDeserialized
OnDeserialized_Derived
OnDeserialized_Derived_Derived
OnSerializing
OnSerializing_Derived
OnSerializing_Derived_Derived
OnSerialized
OnSerialized_Derived
OnSerialized_Derived_Derived", string.Join(Environment.NewLine, e.ToArray()));
}
#if !(NET20 || SILVERLIGHT)
[Test]
public void DerivedDerivedSerializationEvents_DataContractSerializer()
{
string xml = @"<DerivedDerivedSerializationEventOrderTestObject xmlns=""http://schemas.datacontract.org/2004/07/Newtonsoft.Json.Tests.Serialization"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""/>";
DataContractSerializer ss = new DataContractSerializer(typeof(DerivedDerivedSerializationEventOrderTestObject));
DerivedDerivedSerializationEventOrderTestObject c = (DerivedDerivedSerializationEventOrderTestObject)ss.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
MemoryStream ms = new MemoryStream();
ss.WriteObject(ms, c);
IList<string> e = c.GetEvents();
Assert.AreEqual(@"OnDeserializing
OnDeserializing_Derived
OnDeserializing_Derived_Derived
OnDeserialized
OnDeserialized_Derived
OnDeserialized_Derived_Derived
OnSerializing
OnSerializing_Derived
OnSerializing_Derived_Derived
OnSerialized
OnSerialized_Derived
OnSerialized_Derived_Derived", string.Join(Environment.NewLine, e.ToArray()));
}
#endif
}
}
public class SerializationEventOrderTestObject
{
protected IList<string> Events { get; private set; }
public SerializationEventOrderTestObject()
{
Events = new List<string>();
}
public IList<string> GetEvents()
{
return Events;
}
[OnSerializing]
internal void OnSerializingMethod(StreamingContext context)
{
Events.Add("OnSerializing");
}
[OnSerialized]
internal void OnSerializedMethod(StreamingContext context)
{
Events.Add("OnSerialized");
}
[OnDeserializing]
internal void OnDeserializingMethod(StreamingContext context)
{
Events.Add("OnDeserializing");
}
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
{
Events.Add("OnDeserialized");
}
}
public class DerivedSerializationEventOrderTestObject : SerializationEventOrderTestObject
{
[OnSerializing]
internal new void OnSerializingMethod(StreamingContext context)
{
Events.Add("OnSerializing_Derived");
}
[OnSerialized]
internal new void OnSerializedMethod(StreamingContext context)
{
Events.Add("OnSerialized_Derived");
}
[OnDeserializing]
internal new void OnDeserializingMethod(StreamingContext context)
{
Events.Add("OnDeserializing_Derived");
}
[OnDeserialized]
internal new void OnDeserializedMethod(StreamingContext context)
{
Events.Add("OnDeserialized_Derived");
}
}
public class DerivedDerivedSerializationEventOrderTestObject : DerivedSerializationEventOrderTestObject
{
[OnSerializing]
internal new void OnSerializingMethod(StreamingContext context)
{
Events.Add("OnSerializing_Derived_Derived");
}
[OnSerialized]
internal new void OnSerializedMethod(StreamingContext context)
{
Events.Add("OnSerialized_Derived_Derived");
}
[OnDeserializing]
internal new void OnDeserializingMethod(StreamingContext context)
{
Events.Add("OnDeserializing_Derived_Derived");
}
[OnDeserialized]
internal new void OnDeserializedMethod(StreamingContext context)
{
Events.Add("OnDeserialized_Derived_Derived");
}
}
}
+131 -15
View File
@@ -110,7 +110,9 @@ namespace Newtonsoft.Json
using (StringWriter writer = StringUtils.CreateStringWriter(64))
{
WriteDateTimeString(writer, updatedDateTime, updatedDateTime.GetUtcOffset(), updatedDateTime.Kind, format, '"');
writer.Write('"');
WriteDateTimeString(writer, updatedDateTime, updatedDateTime.GetUtcOffset(), updatedDateTime.Kind, format);
writer.Write('"');
return writer.ToString();
}
}
@@ -158,47 +160,44 @@ namespace Newtonsoft.Json
{
using (StringWriter writer = StringUtils.CreateStringWriter(64))
{
WriteDateTimeOffsetString(writer, value, format, null, CultureInfo.InvariantCulture, '"');
writer.Write('"');
WriteDateTimeOffsetString(writer, value, format, null, CultureInfo.InvariantCulture);
writer.Write('"');
return writer.ToString();
}
}
internal static void WriteDateTimeOffsetString(TextWriter writer, DateTimeOffset value, DateFormatHandling format, string formatString, CultureInfo culture, char quoteChar)
internal static void WriteDateTimeOffsetString(TextWriter writer, DateTimeOffset value, DateFormatHandling format, string formatString, CultureInfo culture)
{
if (string.IsNullOrEmpty(formatString))
{
WriteDateTimeString(writer, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format, quoteChar);
WriteDateTimeString(writer, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format);
}
else
{
writer.Write(quoteChar);
writer.Write(value.ToString(formatString, culture));
writer.Write(quoteChar);
}
}
#endif
internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, string formatString, CultureInfo culture, char quoteChar)
internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, string formatString, CultureInfo culture)
{
if (string.IsNullOrEmpty(formatString))
{
WriteDateTimeString(writer, value, value.GetUtcOffset(), value.Kind, format, quoteChar);
WriteDateTimeString(writer, value, value.GetUtcOffset(), value.Kind, format);
}
else
{
writer.Write(quoteChar);
writer.Write(value.ToString(formatString, culture));
writer.Write(quoteChar);
}
}
internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind, DateFormatHandling format, char quoteChar)
internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind, DateFormatHandling format)
{
if (format == DateFormatHandling.MicrosoftDateFormat)
{
long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, offset);
writer.Write(quoteChar);
writer.Write(@"\/Date(");
writer.Write(javaScriptTicks);
@@ -214,11 +213,9 @@ namespace Newtonsoft.Json
}
writer.Write(@")\/");
writer.Write(quoteChar);
}
else
{
writer.Write(quoteChar);
writer.Write(value.ToString(@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture));
switch (kind)
@@ -231,7 +228,6 @@ namespace Newtonsoft.Json
break;
}
writer.Write(quoteChar);
}
}
@@ -727,6 +723,126 @@ namespace Newtonsoft.Json
return IsJsonPrimitiveTypeCode(ConvertUtils.GetTypeCode(type));
}
internal static bool TryParseDateTime(string s, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt)
{
if (s.Length > 0)
{
if (s[0] == '/')
{
if (s.StartsWith("/Date(", StringComparison.Ordinal) && s.EndsWith(")/", StringComparison.Ordinal))
{
return TryParseDateMicrosoft(s, dateParseHandling, dateTimeZoneHandling, out dt);
}
}
else if (char.IsDigit(s[0]) && s.Length >= 19 && s.Length <= 40)
{
return TryParseDateIso(s, dateParseHandling, dateTimeZoneHandling, out dt);
}
}
dt = null;
return false;
}
private static bool TryParseDateIso(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt)
{
const string isoDateFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFK";
#if !NET20
if (dateParseHandling == DateParseHandling.DateTimeOffset)
{
DateTimeOffset dateTimeOffset;
if (DateTimeOffset.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
{
dt = dateTimeOffset;
return true;
}
}
else
#endif
{
DateTime dateTime;
if (DateTime.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime))
{
dateTime = EnsureDateTime(dateTime, dateTimeZoneHandling);
dt = dateTime;
return true;
}
}
dt = null;
return false;
}
private static bool TryParseDateMicrosoft(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt)
{
string value = text.Substring(6, text.Length - 8);
DateTimeKind kind = DateTimeKind.Utc;
int index = value.IndexOf('+', 1);
if (index == -1)
index = value.IndexOf('-', 1);
TimeSpan offset = TimeSpan.Zero;
if (index != -1)
{
kind = DateTimeKind.Local;
offset = ReadOffset(value.Substring(index));
value = value.Substring(0, index);
}
long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
DateTime utcDateTime = ConvertJavaScriptTicksToDateTime(javaScriptTicks);
#if !NET20
if (dateParseHandling == DateParseHandling.DateTimeOffset)
{
dt = new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset);
return true;
}
else
#endif
{
DateTime dateTime;
switch (kind)
{
case DateTimeKind.Unspecified:
dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
break;
case DateTimeKind.Local:
dateTime = utcDateTime.ToLocalTime();
break;
default:
dateTime = utcDateTime;
break;
}
dt = EnsureDateTime(dateTime, dateTimeZoneHandling);
return true;
}
}
private static TimeSpan ReadOffset(string offsetText)
{
bool negative = (offsetText[0] == '-');
int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
int minutes = 0;
if (offsetText.Length >= 5)
minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes);
if (negative)
offset = offset.Negate();
return offset;
}
#region Serialize
/// <summary>
/// Serializes the specified object to a JSON string.
+14 -112
View File
@@ -137,21 +137,21 @@ namespace Newtonsoft.Json
if (_dateParseHandling != DateParseHandling.None)
{
if (text.Length > 0)
DateParseHandling dateParseHandling;
if (_readType == ReadType.ReadAsDateTime)
dateParseHandling = DateParseHandling.DateTime;
#if !NET20
else if (_readType == ReadType.ReadAsDateTimeOffset)
dateParseHandling = DateParseHandling.DateTimeOffset;
#endif
else
dateParseHandling = _dateParseHandling;
object dt;
if (JsonConvert.TryParseDateTime(text, dateParseHandling, DateTimeZoneHandling, out dt))
{
if (text[0] == '/')
{
if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
{
ParseDateMicrosoft(text);
return;
}
}
else if (char.IsDigit(text[0]) && text.Length >= 19 && text.Length <= 40)
{
if (ParseDateIso(text))
return;
}
SetToken(JsonToken.Date, dt);
return;
}
}
@@ -160,88 +160,6 @@ namespace Newtonsoft.Json
}
}
private bool ParseDateIso(string text)
{
const string isoDateFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFK";
#if !NET20
if (_readType == ReadType.ReadAsDateTimeOffset || (_readType == ReadType.Read && _dateParseHandling == DateParseHandling.DateTimeOffset))
{
DateTimeOffset dateTimeOffset;
if (DateTimeOffset.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset))
{
SetToken(JsonToken.Date, dateTimeOffset);
return true;
}
}
else
#endif
{
DateTime dateTime;
if (DateTime.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime))
{
dateTime = JsonConvert.EnsureDateTime(dateTime, DateTimeZoneHandling);
SetToken(JsonToken.Date, dateTime);
return true;
}
}
return false;
}
private void ParseDateMicrosoft(string text)
{
string value = text.Substring(6, text.Length - 8);
DateTimeKind kind = DateTimeKind.Utc;
int index = value.IndexOf('+', 1);
if (index == -1)
index = value.IndexOf('-', 1);
TimeSpan offset = TimeSpan.Zero;
if (index != -1)
{
kind = DateTimeKind.Local;
offset = ReadOffset(value.Substring(index));
value = value.Substring(0, index);
}
long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
#if !NET20
if (_readType == ReadType.ReadAsDateTimeOffset || (_readType == ReadType.Read && _dateParseHandling == DateParseHandling.DateTimeOffset))
{
SetToken(JsonToken.Date, new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset));
}
else
#endif
{
DateTime dateTime;
switch (kind)
{
case DateTimeKind.Unspecified:
dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified);
break;
case DateTimeKind.Local:
dateTime = utcDateTime.ToLocalTime();
break;
default:
dateTime = utcDateTime;
break;
}
dateTime = JsonConvert.EnsureDateTime(dateTime, DateTimeZoneHandling);
SetToken(JsonToken.Date, dateTime);
}
}
private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int dstOffset, int count)
{
const int charByteCount = 2;
@@ -368,22 +286,6 @@ namespace Newtonsoft.Json
return true;
}
private static TimeSpan ReadOffset(string offsetText)
{
bool negative = (offsetText[0] == '-');
int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
int minutes = 0;
if (offsetText.Length >= 5)
minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture);
TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes);
if (negative)
offset = offset.Negate();
return offset;
}
/// <summary>
/// Reads the next JSON token from the stream.
/// </summary>
+28 -2
View File
@@ -211,6 +211,28 @@ namespace Newtonsoft.Json
_writer.Write(':');
}
public override void WritePropertyName(string name, bool escape)
{
InternalWritePropertyName(name);
if (escape)
{
JavaScriptUtils.WriteEscapedJavaScriptString(_writer, name, _quoteChar, _quoteName, GetCharEscapeFlags(), StringEscapeHandling);
}
else
{
if (_quoteName)
_writer.Write(_quoteChar);
_writer.Write(name);
if (_quoteName)
_writer.Write(_quoteChar);
}
_writer.Write(':');
}
private bool[] GetCharEscapeFlags()
{
if (StringEscapeHandling == StringEscapeHandling.EscapeHtml)
@@ -484,7 +506,9 @@ namespace Newtonsoft.Json
{
InternalWriteValue(JsonToken.Date);
value = JsonConvert.EnsureDateTime(value, DateTimeZoneHandling);
JsonConvert.WriteDateTimeString(_writer, value, DateFormatHandling, DateFormatString, Culture, _quoteChar);
_writer.Write(_quoteChar);
JsonConvert.WriteDateTimeString(_writer, value, DateFormatHandling, DateFormatString, Culture);
_writer.Write(_quoteChar);
}
/// <summary>
@@ -515,7 +539,9 @@ namespace Newtonsoft.Json
public override void WriteValue(DateTimeOffset value)
{
InternalWriteValue(JsonToken.Date);
JsonConvert.WriteDateTimeOffsetString(_writer, value, DateFormatHandling, DateFormatString, Culture, _quoteChar);
_writer.Write(_quoteChar);
JsonConvert.WriteDateTimeOffsetString(_writer, value, DateFormatHandling, DateFormatString, Culture);
_writer.Write(_quoteChar);
}
#endif
+5
View File
@@ -411,6 +411,11 @@ namespace Newtonsoft.Json
InternalWritePropertyName(name);
}
public virtual void WritePropertyName(string name, bool escape)
{
WritePropertyName(name);
}
internal void InternalWritePropertyName(string name)
{
_currentPosition.PropertyName = name;
+89 -1
View File
@@ -37,7 +37,7 @@ namespace Newtonsoft.Json.Linq
/// <summary>
/// Represents a value in JSON (string, integer, date, etc).
/// </summary>
public class JValue : JToken, IEquatable<JValue>, IFormattable, IComparable, IComparable<JValue>
public class JValue : JToken, IEquatable<JValue>, IFormattable, IComparable, IComparable<JValue>, IConvertible
{
private JTokenType _valueType;
private object _value;
@@ -830,5 +830,93 @@ namespace Newtonsoft.Json.Linq
return Compare(_valueType, _value, obj._value);
}
TypeCode IConvertible.GetTypeCode()
{
if (_value == null)
return TypeCode.Empty;
return System.Type.GetTypeCode(_value.GetType());
}
bool IConvertible.ToBoolean(IFormatProvider provider)
{
return Convert.ToBoolean(_value, CultureInfo.InvariantCulture);
}
char IConvertible.ToChar(IFormatProvider provider)
{
return Convert.ToChar(_value, CultureInfo.InvariantCulture);
}
sbyte IConvertible.ToSByte(IFormatProvider provider)
{
return Convert.ToSByte(_value, CultureInfo.InvariantCulture);
}
byte IConvertible.ToByte(IFormatProvider provider)
{
return Convert.ToByte(_value, CultureInfo.InvariantCulture);
}
short IConvertible.ToInt16(IFormatProvider provider)
{
return Convert.ToInt16(_value, CultureInfo.InvariantCulture);
}
ushort IConvertible.ToUInt16(IFormatProvider provider)
{
return Convert.ToUInt16(_value, CultureInfo.InvariantCulture);
}
int IConvertible.ToInt32(IFormatProvider provider)
{
return Convert.ToInt32(_value, CultureInfo.InvariantCulture);
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
return Convert.ToUInt32(_value, CultureInfo.InvariantCulture);
}
long IConvertible.ToInt64(IFormatProvider provider)
{
return Convert.ToInt64(_value, CultureInfo.InvariantCulture);
}
ulong IConvertible.ToUInt64(IFormatProvider provider)
{
return Convert.ToUInt64(_value, CultureInfo.InvariantCulture);
}
float IConvertible.ToSingle(IFormatProvider provider)
{
return Convert.ToSingle(_value, CultureInfo.InvariantCulture);
}
double IConvertible.ToDouble(IFormatProvider provider)
{
return Convert.ToDouble(_value, CultureInfo.InvariantCulture);
}
decimal IConvertible.ToDecimal(IFormatProvider provider)
{
return Convert.ToDecimal(_value, CultureInfo.InvariantCulture);
}
DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
#if !NET20
if (_value is DateTimeOffset)
return ((DateTimeOffset) _value).DateTime;
#endif
return Convert.ToDateTime(_value, CultureInfo.InvariantCulture);
}
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
{
return Convert.ChangeType(_value, conversionType, provider);
}
}
}
@@ -87,6 +87,6 @@ using System.Security;
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
[assembly: AssemblyFileVersion("4.5.11.15906")]
[assembly: AssemblyFileVersion("4.5.11.15911")]
[assembly: CLSCompliant(true)]
@@ -547,9 +547,6 @@ namespace Newtonsoft.Json.Serialization
private void ResolveCallbackMethods(JsonContract contract, Type t)
{
if (t.BaseType() != null)
ResolveCallbackMethods(contract, t.BaseType());
List<MethodInfo> onSerializing;
List<MethodInfo> onSerialized;
List<MethodInfo> onDeserializing;
@@ -878,7 +878,18 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
{
try
{
keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
if (contract.DictionaryKeyType == typeof(DateTime) && JsonConvert.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTime, reader.DateTimeZoneHandling, out keyValue))
{
}
#if !NET20
else if (contract.DictionaryKeyType == typeof(DateTimeOffset) && JsonConvert.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTimeOffset, reader.DateTimeZoneHandling, out keyValue))
{
}
#endif
else
{
keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
}
}
catch (Exception ex)
{
@@ -32,6 +32,7 @@ using System.Dynamic;
#endif
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Security;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Utilities;
@@ -833,7 +834,8 @@ To fix this error either change the environment to be fully trusted, change the
foreach (DictionaryEntry entry in d)
{
string propertyName = GetPropertyName(entry);
bool escape;
string propertyName = GetPropertyName(writer, entry, out escape);
propertyName = (contract.PropertyNameResolver != null)
? contract.PropertyNameResolver(propertyName)
@@ -846,7 +848,7 @@ To fix this error either change the environment to be fully trusted, change the
if (ShouldWriteReference(value, null, valueContract, contract, member))
{
writer.WritePropertyName(propertyName);
writer.WritePropertyName(propertyName, escape);
WriteReference(writer, value);
}
else
@@ -854,7 +856,7 @@ To fix this error either change the environment to be fully trusted, change the
if (!CheckForCircularReference(writer, value, null, valueContract, contract, member))
continue;
writer.WritePropertyName(propertyName);
writer.WritePropertyName(propertyName, escape);
SerializeValue(writer, value, valueContract, null, contract, member);
}
@@ -875,16 +877,43 @@ To fix this error either change the environment to be fully trusted, change the
OnSerialized(writer, contract, values.UnderlyingDictionary);
}
private string GetPropertyName(DictionaryEntry entry)
private string GetPropertyName(JsonWriter writer, DictionaryEntry entry, out bool escape)
{
object key = entry.Key;
string propertyName;
if (ConvertUtils.IsConvertible(entry.Key))
return Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
else if (TryConvertToString(entry.Key, entry.Key.GetType(), out propertyName))
if (key is DateTime)
{
escape = false;
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
JsonConvert.WriteDateTimeString(sw, (DateTime)key, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
return sw.ToString();
}
#if !NET20
else if (key is DateTimeOffset)
{
escape = false;
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
JsonConvert.WriteDateTimeOffsetString(sw, (DateTimeOffset)key, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
return sw.ToString();
}
#endif
else if (ConvertUtils.IsConvertible(key))
{
escape = true;
return Convert.ToString(key, CultureInfo.InvariantCulture);
}
else if (TryConvertToString(key, key.GetType(), out propertyName))
{
escape = true;
return propertyName;
}
else
return entry.Key.ToString();
{
escape = true;
return key.ToString();
}
}
private void HandleError(JsonWriter writer, int initialDepth)
@@ -119,18 +119,7 @@ namespace Newtonsoft.Json.Serialization
public static DataContractAttribute GetDataContractAttribute(Type type)
{
// DataContractAttribute does not have inheritance
Type currentType = type;
while (currentType != null)
{
DataContractAttribute result = CachedAttributeGetter<DataContractAttribute>.GetAttribute(currentType.GetCustomAttributeProvider());
if (result != null)
return result;
currentType = currentType.BaseType();
}
return null;
return CachedAttributeGetter<DataContractAttribute>.GetAttribute(type.GetCustomAttributeProvider());
}
public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo)