New features:
Added support for deserializing to an anonymous type with the DeserializeAnonymousType method. Support for reading, writing and serializing the new DateTimeOffset type. Added IsoDateTimeConverter. Converts DateTimes and DateTimeOffsets to and from the ISO 8601 format. Added JavaScriptDateTimeConverter. Converts DateTimes and DateTimeOffsets to and from a JavaScript date constructor. XmlNodeConverter handles serializing and deserializing JavaScript constructors. Ability to force XmlNodeConverter to write a value in an array. Logic is controlled by an attribute, json:Array="true". Changes: Dates are now serialized in a JSON complient manner, similar to ASP.NET's JavaScriptSerializer or WCF's DataContractJsonSerializer - http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx Removed the AspNetAjaxDateTimeConverter.
This commit is contained in:
@@ -1,70 +0,0 @@
|
||||
#region License
|
||||
// Copyright (c) 2007 James Newton-King
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
// restriction, including without limitation the rights to use,
|
||||
// copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following
|
||||
// conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class AspNetAjaxDateTimeConverterTest
|
||||
{
|
||||
public class DateTimeTestClass
|
||||
{
|
||||
public string PreField;
|
||||
public DateTime DateTimeField;
|
||||
public string PostField;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Serialize()
|
||||
{
|
||||
DateTimeTestClass c = new DateTimeTestClass();
|
||||
c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 12);
|
||||
c.PreField = "Pre";
|
||||
c.PostField = "Post";
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(c, new AspNetAjaxDateTimeConverter());
|
||||
|
||||
Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""@1229083932012@"",""PostField"":""Post""}", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeSerialize()
|
||||
{
|
||||
DateTimeTestClass c =
|
||||
JavaScriptConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":""@1229083932012@"",""PostField"":""Post""}", new AspNetAjaxDateTimeConverter());
|
||||
|
||||
Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 12), c.DateTimeField);
|
||||
Assert.AreEqual("Pre", c.PreField);
|
||||
Assert.AreEqual("Post", c.PostField);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
public class DateTimeTestClass
|
||||
{
|
||||
public string PreField { get; set; }
|
||||
public DateTime DateTimeField { get; set; }
|
||||
public string PostField { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
public class IsoDateTimeConverterTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void SerializeDateTime()
|
||||
{
|
||||
IsoDateTimeConverter converter = new IsoDateTimeConverter();
|
||||
|
||||
DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc);
|
||||
string result;
|
||||
|
||||
result = JavaScriptConvert.SerializeObject(d, converter);
|
||||
Assert.AreEqual(@"""2000-12-15T22:11:03.0550000Z""", result);
|
||||
|
||||
Assert.AreEqual(d, JavaScriptConvert.DeserializeObject<DateTime>(result, converter));
|
||||
|
||||
d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Local);
|
||||
result = JavaScriptConvert.SerializeObject(d, converter);
|
||||
Assert.AreEqual(@"""2000-12-15T22:11:03.0550000" + d.GetLocalOffset() + @"""", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeDateTimeOffset()
|
||||
{
|
||||
IsoDateTimeConverter converter = new IsoDateTimeConverter();
|
||||
|
||||
DateTimeOffset d = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero);
|
||||
string result;
|
||||
|
||||
result = JavaScriptConvert.SerializeObject(d, converter);
|
||||
Assert.AreEqual(@"""2000-12-15T22:11:03.0550000+00:00""", result);
|
||||
|
||||
Assert.AreEqual(d, JavaScriptConvert.DeserializeObject<DateTimeOffset>(result, converter));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeUTC()
|
||||
{
|
||||
DateTimeTestClass c = new DateTimeTestClass();
|
||||
c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime();
|
||||
c.PreField = "Pre";
|
||||
c.PostField = "Post";
|
||||
string json = JavaScriptConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
|
||||
Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12.0000000Z"",""PostField"":""Post""}", json);
|
||||
|
||||
//test the other edge case too
|
||||
c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime();
|
||||
c.PreField = "Pre";
|
||||
c.PostField = "Post";
|
||||
json = JavaScriptConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
|
||||
Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01.0000000Z"",""PostField"":""Post""}", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeUTC()
|
||||
{
|
||||
DateTimeTestClass c =
|
||||
JavaScriptConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
|
||||
|
||||
Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField);
|
||||
Assert.AreEqual("Pre", c.PreField);
|
||||
Assert.AreEqual("Post", c.PostField);
|
||||
|
||||
DateTimeTestClass c2 =
|
||||
JavaScriptConvert.DeserializeObject<DateTimeTestClass>(@"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
|
||||
|
||||
Assert.AreEqual(new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(), c2.DateTimeField);
|
||||
Assert.AreEqual("Pre", c2.PreField);
|
||||
Assert.AreEqual("Post", c2.PostField);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeShouldChangeNonUTCDates()
|
||||
{
|
||||
DateTimeTestClass c = new DateTimeTestClass();
|
||||
c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Local);
|
||||
c.PreField = "Pre";
|
||||
c.PostField = "Post";
|
||||
string json = JavaScriptConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); //note that this fails without the Utc converter...
|
||||
c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc);
|
||||
string json2 = JavaScriptConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
|
||||
Assert.AreNotEqual(json, json2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,7 @@ using NUnit.Framework;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class JavaScriptConvertTest
|
||||
public class JavaScriptConvertTest : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void EscapeJavaScriptString()
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
public class JavaScriptDateTimeConverterTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void SerializeDateTime()
|
||||
{
|
||||
JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
|
||||
|
||||
DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc);
|
||||
string result;
|
||||
|
||||
result = JavaScriptConvert.SerializeObject(d, converter);
|
||||
Assert.AreEqual("new Date(976918263055)", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeDateTimeOffset()
|
||||
{
|
||||
JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
|
||||
|
||||
DateTimeOffset now = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero);
|
||||
string result;
|
||||
|
||||
result = JavaScriptConvert.SerializeObject(now, converter);
|
||||
Assert.AreEqual("new Date(976918263055)", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeDateTime()
|
||||
{
|
||||
JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
|
||||
|
||||
DateTime result = JavaScriptConvert.DeserializeObject<DateTime>("new Date(976918263055)", converter);
|
||||
Assert.AreEqual(new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializeDateTimeOffset()
|
||||
{
|
||||
JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
|
||||
DateTimeOffset start = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero);
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(start, converter);
|
||||
|
||||
DateTimeOffset result = JavaScriptConvert.DeserializeObject<DateTimeOffset>(json, converter);
|
||||
Assert.AreEqual(new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,7 @@ using System.IO;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class JsonReaderTest
|
||||
public class JsonReaderTest : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void YahooFinance()
|
||||
|
||||
@@ -35,20 +35,25 @@ using System.Xml.Serialization;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Net.Mail;
|
||||
using System.Web.Script.Serialization;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
public class Product
|
||||
{
|
||||
public string Name;
|
||||
public DateTime Expiry;
|
||||
public DateTime Expiry = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
public decimal Price;
|
||||
public string[] Sizes;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Product)
|
||||
return ((Product)obj).Name == Name;
|
||||
{
|
||||
Product p = (Product)obj;
|
||||
|
||||
return (p.Name == Name && p.Expiry == Expiry && p.Price == Price);
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
@@ -74,7 +79,7 @@ namespace Newtonsoft.Json.Tests
|
||||
public class Store
|
||||
{
|
||||
public StoreColor Color = StoreColor.Yellow;
|
||||
public DateTime Establised = new DateTime(2010, 1, 22);
|
||||
public DateTimeOffset Establised = new DateTimeOffset(2010, 1, 22, 1, 1, 1, TimeSpan.Zero);
|
||||
public double Width = 1.1;
|
||||
public int Employees = 999;
|
||||
public int[] RoomsPerFloor = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
@@ -94,7 +99,7 @@ namespace Newtonsoft.Json.Tests
|
||||
|
||||
Product rocket = new Product();
|
||||
rocket.Name = "Rocket";
|
||||
rocket.Expiry = new DateTime(2000, 2, 2, 23, 1, 30);
|
||||
rocket.Expiry = new DateTime(2000, 2, 2, 23, 1, 30, DateTimeKind.Utc);
|
||||
Product alien = new Product();
|
||||
alien.Name = "Alien";
|
||||
|
||||
@@ -111,8 +116,7 @@ namespace Newtonsoft.Json.Tests
|
||||
White
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class JsonSerializerTest
|
||||
public class JsonSerializerTest : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void PersonTypedObjectDeserialization()
|
||||
@@ -626,6 +630,46 @@ keyword such as type of business.""
|
||||
Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DateTime()
|
||||
{
|
||||
List<DateTime> testDates = new List<DateTime> {
|
||||
new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Local),
|
||||
new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
|
||||
new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc),
|
||||
new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local),
|
||||
new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
|
||||
new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc),
|
||||
};
|
||||
string result;
|
||||
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<DateTime>));
|
||||
s.WriteObject(ms, testDates);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
StreamReader sr = new StreamReader(ms);
|
||||
|
||||
string expected = sr.ReadToEnd();
|
||||
|
||||
result = JavaScriptConvert.SerializeObject(testDates);
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DateTimeOffset()
|
||||
{
|
||||
List<DateTimeOffset> testDates = new List<DateTimeOffset> {
|
||||
new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
|
||||
new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
|
||||
new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
|
||||
new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
|
||||
};
|
||||
|
||||
string result = JavaScriptConvert.SerializeObject(testDates);
|
||||
Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NonStringKeyDictionary()
|
||||
{
|
||||
@@ -645,10 +689,27 @@ keyword such as type of business.""
|
||||
[Test]
|
||||
public void AnonymousObjectSerialization()
|
||||
{
|
||||
var anonymous = new { StringValue = "I am a string", IntValue = int.MaxValue };
|
||||
var anonymous =
|
||||
new
|
||||
{
|
||||
StringValue = "I am a string",
|
||||
IntValue = int.MaxValue,
|
||||
NestedAnonymous = new { NestedValue = byte.MaxValue },
|
||||
NestedArray = new[] { 1, 2 },
|
||||
Product = new Product() { Name = "TestProduct" }
|
||||
};
|
||||
|
||||
string json = JavaScriptConvert.SerializeObject(anonymous);
|
||||
Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647}", json);
|
||||
Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647,""NestedAnonymous"":{""NestedValue"":255},""NestedArray"":[1,2],""Product"":{""Name"":""TestProduct"",""Expiry"":""\/Date(946684800000)\/"",""Price"":0,""Sizes"":null}}", json);
|
||||
|
||||
anonymous = JavaScriptConvert.DeserializeAnonymousType(json, anonymous);
|
||||
Assert.AreEqual("I am a string", anonymous.StringValue);
|
||||
Assert.AreEqual(int.MaxValue, anonymous.IntValue);
|
||||
Assert.AreEqual(255, anonymous.NestedAnonymous.NestedValue);
|
||||
Assert.AreEqual(2, anonymous.NestedArray.Length);
|
||||
Assert.AreEqual(1, anonymous.NestedArray[0]);
|
||||
Assert.AreEqual(2, anonymous.NestedArray[1]);
|
||||
Assert.AreEqual("TestProduct", anonymous.Product.Name);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -668,7 +729,7 @@ keyword such as type of business.""
|
||||
|
||||
jsonSerializer.Serialize(sw, collection);
|
||||
|
||||
Assert.AreEqual(@"[{""Name"":""Test1"",""Expiry"":new Date(-59011459200000),""Price"":0,""Sizes"":null},{""Name"":""Test2"",""Expiry"":new Date(-59011459200000),""Price"":0,""Sizes"":null},{""Name"":""Test3"",""Expiry"":new Date(-59011459200000),""Price"":0,""Sizes"":null}]",
|
||||
Assert.AreEqual(@"[{""Name"":""Test1"",""Expiry"":""\/Date(946684800000)\/"",""Price"":0,""Sizes"":null},{""Name"":""Test2"",""Expiry"":""\/Date(946684800000)\/"",""Price"":0,""Sizes"":null},{""Name"":""Test3"",""Expiry"":""\/Date(946684800000)\/"",""Price"":0,""Sizes"":null}]",
|
||||
sw.GetStringBuilder().ToString());
|
||||
|
||||
ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection));
|
||||
@@ -687,13 +748,18 @@ keyword such as type of business.""
|
||||
StringWriter sw = new StringWriter();
|
||||
jsonSerializer.Serialize(sw, s1);
|
||||
|
||||
Assert.AreEqual(@"{""Color"":2,""Establised"":new Date(1264118400000),""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""Expiry"":new Date(949532490000),""Price"":0},{""Name"":""Alien"",""Expiry"":new Date(-59011459200000),""Price"":0}]}", sw.GetStringBuilder().ToString());
|
||||
//JavaScriptConvert.ConvertDateTimeToJavaScriptTicks(s1.Establised.DateTime)
|
||||
|
||||
Assert.AreEqual(@"{""Color"":2,""Establised"":""\/Date(1264122061000+0000)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""鲣�能\\'{new Date(12345);}[222]_礍渤~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""Expiry"":""\/Date(949532490000)\/"",""Price"":0},{""Name"":""Alien"",""Expiry"":""\/Date(946684800000)\/"",""Price"":0}]}", sw.GetStringBuilder().ToString());
|
||||
|
||||
Store s2 = (Store)jsonSerializer.Deserialize(new JsonReader(new StringReader("{}")), typeof(Store));
|
||||
Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s2.Escape);
|
||||
|
||||
Store s3 = (Store)jsonSerializer.Deserialize(new JsonReader(new StringReader(@"{""Escape"":null}")), typeof(Store));
|
||||
Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s3.Escape);
|
||||
|
||||
Store s4 = (Store)jsonSerializer.Deserialize(new JsonReader(new StringReader(@"{""Color"":2,""Establised"":""\/Date(1264071600000+1300)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""鲣�能\\'{new Date(12345);}[222]_礍渤~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""Expiry"":""\/Date(949485690000+1300)\/"",""Price"":0},{""Name"":""Alien"",""Expiry"":""\/Date(946638000000)\/"",""Price"":0}]}")), typeof(Store));
|
||||
Assert.AreEqual(s1.Establised, s3.Establised);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,7 @@ using System.IO;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class JsonWriterTest
|
||||
public class JsonWriterTest : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void ValueFormatting()
|
||||
|
||||
@@ -34,8 +34,7 @@ using System.IO;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class LinqToJsonTest
|
||||
public class LinqToJsonTest : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void ObjectParse()
|
||||
@@ -226,12 +225,16 @@ keyword such as type of business.""
|
||||
[Test]
|
||||
public void JTokenToStringTypes()
|
||||
{
|
||||
string json = @"{""Color"":2,""Establised"":new Date(1264118400000),""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""Expiry"":new Date(949532490000),""Price"":0},{""Name"":""Alien"",""Expiry"":new Date(-59011459200000),""Price"":0}]}";
|
||||
string json = @"{""Color"":2,""Establised"":new Date(1264118400000),""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""Expiry"":new Date(949532490000),""Price"":0},{""Name"":""Alien"",""Expiry"":new Date(-62135596800000),""Price"":0}]}";
|
||||
|
||||
JObject o = JObject.Parse(json);
|
||||
|
||||
Assert.AreEqual(@"""Establised"": new Date(1264118400000)", o.Property("Establised").ToString());
|
||||
Assert.AreEqual(@"new Date(1264118400000)", o.Property("Establised").Value.ToString());
|
||||
Assert.AreEqual(@"""Establised"": new Date(
|
||||
1264118400000
|
||||
)", o.Property("Establised").ToString());
|
||||
Assert.AreEqual(@"new Date(
|
||||
1264118400000
|
||||
)", o.Property("Establised").Value.ToString());
|
||||
Assert.AreEqual(@"""Width"": 1.1", o.Property("Width").ToString());
|
||||
Assert.AreEqual(@"1.1", o.Property("Width").Value.ToString());
|
||||
Assert.AreEqual(@"""Open"": false", o.Property("Open").ToString());
|
||||
@@ -271,13 +274,13 @@ keyword such as type of business.""
|
||||
JArray a =
|
||||
new JArray(
|
||||
o,
|
||||
new DateTime(2000, 10, 10),
|
||||
new DateTime(2000, 10, 10, 0, 0, 0, DateTimeKind.Utc),
|
||||
55,
|
||||
new JArray(
|
||||
"1",
|
||||
2,
|
||||
3.0,
|
||||
new DateTime(4, 5, 6, 7, 8, 9)
|
||||
new DateTime(4, 5, 6, 7, 8, 9, DateTimeKind.Utc)
|
||||
),
|
||||
new JConstructor(
|
||||
"ConstructorName",
|
||||
@@ -295,13 +298,13 @@ keyword such as type of business.""
|
||||
""Test3"": ""Test3Value"",
|
||||
""Test4"": null
|
||||
},
|
||||
new Date(971136000000),
|
||||
""\/Date(971136000000)\/"",
|
||||
55,
|
||||
[
|
||||
""1"",
|
||||
2,
|
||||
3,
|
||||
new Date(-59011459200000)
|
||||
""\/Date(-62030076711000)\/""
|
||||
],
|
||||
new ConstructorName(
|
||||
""param1"",
|
||||
|
||||
@@ -60,16 +60,23 @@
|
||||
<Reference Include="System.ServiceModel.Web">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Extensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AspNetAjaxDateTimeConverterTest.cs" />
|
||||
<Compile Include="DateTimeTestClass.cs" />
|
||||
<Compile Include="IsoDateTimeConverterTests.cs" />
|
||||
<Compile Include="JavaScriptConvertTest.cs" />
|
||||
<Compile Include="JavaScriptDateTimeConverterTests.cs" />
|
||||
<Compile Include="JsonReaderTest.cs" />
|
||||
<Compile Include="JsonSerializerTest.cs" />
|
||||
<Compile Include="JsonWriterTest.cs" />
|
||||
<Compile Include="LinqToJsonTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TestFixtureBase.cs" />
|
||||
<Compile Include="UtcDateTimeConverterTest.cs" />
|
||||
<Compile Include="XmlNodeConverterTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public abstract class TestFixtureBase
|
||||
{
|
||||
public string GetOffset(DateTime value)
|
||||
{
|
||||
TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(value.ToLocalTime());
|
||||
|
||||
return utcOffset.Hours.ToString("+00;-00") + utcOffset.Minutes.ToString("00;00");
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-24
@@ -23,37 +23,26 @@
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
#endregion
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Xml;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
public class AspNetAjaxDateTimeConverter : JsonConverter
|
||||
public class IsoDateTimeConverterTest : TestFixtureBase
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value)
|
||||
[Test]
|
||||
public void ShouldBeAbleToConvertDateTimes()
|
||||
{
|
||||
DateTime dateTime = (DateTime)value;
|
||||
long javaScriptTicks = JavaScriptConvert.ConvertDateTimeToJavaScriptTicks(dateTime);
|
||||
|
||||
writer.WriteValue("@" + javaScriptTicks.ToString(null, CultureInfo.InvariantCulture) + "@");
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType)
|
||||
{
|
||||
string dateTimeText = (string)reader.Value;
|
||||
dateTimeText = dateTimeText.Substring(1, dateTimeText.Length - 2);
|
||||
|
||||
long javaScriptTicks = Convert.ToInt64(dateTimeText);
|
||||
|
||||
return JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type valueType)
|
||||
{
|
||||
return typeof(DateTime).IsAssignableFrom(valueType);
|
||||
IsoDateTimeConverter conv = new IsoDateTimeConverter();
|
||||
Assert.IsTrue(conv.CanConvert(typeof(DateTime)));
|
||||
Assert.IsTrue(conv.CanConvert(typeof(DateTimeOffset)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,11 +29,11 @@ using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class XmlNodeConverterTest
|
||||
public class XmlNodeConverterTest : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void DocumentSerializeIndented()
|
||||
@@ -210,7 +210,7 @@ namespace Newtonsoft.Json.Tests
|
||||
|
||||
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
|
||||
|
||||
XmlDocument deserializedDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
|
||||
XmlDocument deserializedDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
|
||||
|
||||
Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml);
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace Newtonsoft.Json.Tests
|
||||
}
|
||||
}";
|
||||
|
||||
XmlDocument doc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
|
||||
XmlDocument doc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
|
||||
|
||||
string expected = @"<?xml version=""1.0"" standalone=""no""?>
|
||||
<span class=""vevent"">
|
||||
@@ -295,7 +295,7 @@ namespace Newtonsoft.Json.Tests
|
||||
|
||||
string jsonText = JavaScriptConvert.SerializeXmlNode(doc);
|
||||
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
|
||||
|
||||
Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
|
||||
}
|
||||
@@ -322,7 +322,7 @@ namespace Newtonsoft.Json.Tests
|
||||
|
||||
Console.WriteLine(jsonText);
|
||||
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
|
||||
|
||||
Assert.AreEqual(doc.InnerXml, newDoc.InnerXml);
|
||||
}
|
||||
@@ -330,13 +330,89 @@ namespace Newtonsoft.Json.Tests
|
||||
[Test]
|
||||
public void OtherElementDataTypes()
|
||||
{
|
||||
string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""@id"":""2"",""Boolean"":true,""date"":new Date(954374400000)}]}}";
|
||||
string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""@id"":""2"",""Boolean"":true,""date"":""\/Date(954374400000)\/""}]}}";
|
||||
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeerializeXmlNode(jsonText);
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
|
||||
|
||||
string expected = @"<?xml version=""1.0"" standalone=""no""?><root><person id=""1""><Float>2.5</Float><Integer>99</Integer></person><person id=""2""><Boolean>true</Boolean><date>2000-03-30T00:00:00.0000000+13:00</date></person></root>";
|
||||
string expected = @"<?xml version=""1.0"" standalone=""no""?><root><person id=""1""><Float>2.5</Float><Integer>99</Integer></person><person id=""2""><Boolean>true</Boolean><date>2000-03-30T00:00:00Z</date></person></root>";
|
||||
|
||||
Assert.AreEqual(expected, newDoc.InnerXml);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "XmlNodeConverter can only convert JSON that begins with an object.")]
|
||||
public void NoRootObject()
|
||||
{
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(@"[1]");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON root object has multiple properties.")]
|
||||
public void RootObjectMultipleProperties()
|
||||
{
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void JavaScriptConstructor()
|
||||
{
|
||||
string jsonText = @"{root:{r:new Date(34343, 55)}}";
|
||||
|
||||
XmlDocument newDoc = (XmlDocument)JavaScriptConvert.DeserializeXmlNode(jsonText);
|
||||
|
||||
string expected = @"<root><r><-Date>34343</-Date><-Date>55</-Date></r></root>";
|
||||
|
||||
Assert.AreEqual(expected, newDoc.InnerXml);
|
||||
|
||||
string json = JavaScriptConvert.SerializeXmlNode(newDoc);
|
||||
Assert.AreEqual(@"{""root"":{""r"":new Date(""34343"",""55"")}}", json);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ForceJsonArray()
|
||||
{
|
||||
string arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
|
||||
<person id=""1"">
|
||||
<name>Alan</name>
|
||||
<url>http://www.google.com</url>
|
||||
<role json:Array=""true"">Admin</role>
|
||||
</person>
|
||||
</root>";
|
||||
|
||||
XmlDocument arrayDoc = new XmlDocument();
|
||||
arrayDoc.LoadXml(arrayXml);
|
||||
|
||||
string arrayJsonText = JavaScriptConvert.SerializeXmlNode(arrayDoc);
|
||||
Assert.AreEqual(@"{""root"":{""person"":{""@id"":""1"",""name"":""Alan"",""url"":""http://www.google.com"",""role"":[""Admin""]}}}", arrayJsonText);
|
||||
|
||||
arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
|
||||
<person id=""1"">
|
||||
<name>Alan</name>
|
||||
<url>http://www.google.com</url>
|
||||
<role json:Array=""true"">Admin1</role>
|
||||
<role json:Array=""true"">Admin2</role>
|
||||
</person>
|
||||
</root>";
|
||||
|
||||
arrayDoc = new XmlDocument();
|
||||
arrayDoc.LoadXml(arrayXml);
|
||||
|
||||
arrayJsonText = JavaScriptConvert.SerializeXmlNode(arrayDoc);
|
||||
Assert.AreEqual(@"{""root"":{""person"":{""@id"":""1"",""name"":""Alan"",""url"":""http://www.google.com"",""role"":[""Admin1"",""Admin2""]}}}", arrayJsonText);
|
||||
|
||||
arrayXml = @"<root xmlns:json=""http://james.newtonking.com/projects/json"">
|
||||
<person id=""1"">
|
||||
<name>Alan</name>
|
||||
<url>http://www.google.com</url>
|
||||
<role json:Array=""false"">Admin1</role>
|
||||
</person>
|
||||
</root>";
|
||||
|
||||
arrayDoc = new XmlDocument();
|
||||
arrayDoc.LoadXml(arrayXml);
|
||||
|
||||
arrayJsonText = JavaScriptConvert.SerializeXmlNode(arrayDoc);
|
||||
Assert.AreEqual(@"{""root"":{""person"":{""@id"":""1"",""name"":""Alan"",""url"":""http://www.google.com"",""role"":""Admin1""}}}", arrayJsonText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
public class IsoDateTimeConverter : JsonConverter
|
||||
{
|
||||
private const string DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
|
||||
|
||||
private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
|
||||
//private bool _forceUniversalTime;
|
||||
|
||||
//public bool ForceUniversalTime
|
||||
//{
|
||||
// get { return _forceUniversalTime; }
|
||||
// set { _forceUniversalTime = value; }
|
||||
//}
|
||||
|
||||
public DateTimeStyles DateTimeStyles
|
||||
{
|
||||
get { return _dateTimeStyles; }
|
||||
set { _dateTimeStyles = value; }
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value)
|
||||
{
|
||||
string text;
|
||||
|
||||
if (value is DateTime)
|
||||
{
|
||||
DateTime dateTime = (DateTime)value;
|
||||
|
||||
if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
|
||||
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
|
||||
dateTime = dateTime.ToUniversalTime();
|
||||
|
||||
text = dateTime.ToString(DateTimeFormat, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else
|
||||
{
|
||||
DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
|
||||
if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
|
||||
|| (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
|
||||
dateTimeOffset = dateTimeOffset.ToUniversalTime();
|
||||
|
||||
text = dateTimeOffset.ToString(DateTimeFormat, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
writer.WriteValue(text);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType)
|
||||
{
|
||||
if (reader.TokenType != JsonToken.String)
|
||||
throw new Exception(string.Format("Unexpected token parsing date. Expected String, got {0}.", reader.TokenType));
|
||||
|
||||
string dateText = reader.Value.ToString();
|
||||
|
||||
if (objectType == typeof(DateTimeOffset))
|
||||
return DateTimeOffset.Parse(dateText, CultureInfo.InvariantCulture, _dateTimeStyles);
|
||||
|
||||
return DateTime.Parse(dateText, CultureInfo.InvariantCulture, _dateTimeStyles);
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return (typeof(DateTime).IsAssignableFrom(objectType)
|
||||
|| typeof(DateTimeOffset).IsAssignableFrom(objectType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
public class JavaScriptDateTimeConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value)
|
||||
{
|
||||
long ticks;
|
||||
|
||||
if (value is DateTime)
|
||||
{
|
||||
DateTime dateTime = (DateTime)value;
|
||||
DateTime utcDateTime = dateTime.ToUniversalTime();
|
||||
ticks = JavaScriptConvert.ConvertDateTimeToJavaScriptTicks(utcDateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
|
||||
DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime();
|
||||
ticks = JavaScriptConvert.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime);
|
||||
}
|
||||
|
||||
writer.WriteStartConstructor("Date");
|
||||
writer.WriteValue(ticks);
|
||||
writer.WriteEndConstructor();
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType)
|
||||
{
|
||||
if (reader.TokenType != JsonToken.StartConstructor || string.Compare(reader.Value.ToString(), "Date", StringComparison.Ordinal) != 0)
|
||||
throw new Exception(string.Format("Unexpected token or value when parsing date. Token: {0}, Value: {1}", reader.TokenType, reader.Value));
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (reader.TokenType != JsonToken.Integer)
|
||||
throw new Exception(string.Format("Unexpected token parsing date. Expected Integer, got {0}.", reader.TokenType));
|
||||
|
||||
long ticks = (long)reader.Value;
|
||||
|
||||
DateTime d = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(ticks);
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (reader.TokenType != JsonToken.EndConstructor)
|
||||
throw new Exception(string.Format("Unexpected token parsing date. Expected EndConstructor, got {0}.", reader.TokenType));
|
||||
|
||||
if (objectType == typeof(DateTimeOffset))
|
||||
return new DateTimeOffset(d);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return (typeof(DateTime).IsAssignableFrom(objectType)
|
||||
|| typeof(DateTimeOffset).IsAssignableFrom(objectType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
public enum JsonDateTimeSerializationMode
|
||||
{
|
||||
Local,
|
||||
Utc,
|
||||
Unspecified,
|
||||
RoundtripKind
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Linq;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
@@ -40,6 +41,7 @@ namespace Newtonsoft.Json.Converters
|
||||
private const string WhitespaceName = "#whitespace";
|
||||
private const string SignificantWhitespaceName = "#significant-whitespace";
|
||||
private const string DeclarationName = "?xml";
|
||||
private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json";
|
||||
|
||||
#region Writing
|
||||
public override void WriteJson(JsonWriter writer, object value)
|
||||
@@ -106,13 +108,29 @@ namespace Newtonsoft.Json.Converters
|
||||
foreach (KeyValuePair<string, List<XmlNode>> nodeNameGroup in nodesGroupedByName)
|
||||
{
|
||||
List<XmlNode> groupedNodes = nodeNameGroup.Value;
|
||||
bool writeArray;
|
||||
|
||||
if (groupedNodes.Count == 1)
|
||||
{
|
||||
XmlNode singleNode = groupedNodes[0];
|
||||
XmlAttribute jsonArrayAttribute = (singleNode.Attributes != null) ? singleNode.Attributes["Array", JsonNamespaceUri] : null;
|
||||
if (jsonArrayAttribute != null)
|
||||
writeArray = XmlConvert.ToBoolean(jsonArrayAttribute.Value);
|
||||
else
|
||||
writeArray = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeArray = true;
|
||||
}
|
||||
|
||||
if (!writeArray)
|
||||
{
|
||||
SerializeNode(writer, groupedNodes[0], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
string elementNames = nodeNameGroup.Key;
|
||||
writer.WritePropertyName(nodeNameGroup.Key);
|
||||
writer.WriteStartArray();
|
||||
|
||||
@@ -138,7 +156,7 @@ namespace Newtonsoft.Json.Converters
|
||||
if (writePropertyName)
|
||||
writer.WritePropertyName(node.Name);
|
||||
|
||||
if (CollectionUtils.IsNullOrEmpty(node.Attributes) && node.ChildNodes.Count == 1
|
||||
if (ValueAttributes(node.Attributes).Count() == 0 && node.ChildNodes.Count == 1
|
||||
&& node.ChildNodes[0].NodeType == XmlNodeType.Text)
|
||||
{
|
||||
// write elements with a single text child as a name value pair
|
||||
@@ -149,6 +167,20 @@ namespace Newtonsoft.Json.Converters
|
||||
// empty element
|
||||
writer.WriteNull();
|
||||
}
|
||||
else if (node.ChildNodes.OfType<XmlElement>().Where(x => x.Name.StartsWith("-")).Count() > 1)
|
||||
{
|
||||
XmlElement constructorValueElement = node.ChildNodes.OfType<XmlElement>().Where(x => x.Name.StartsWith("-")).First();
|
||||
string constructorName = constructorValueElement.Name.Substring(1);
|
||||
|
||||
writer.WriteStartConstructor(constructorName);
|
||||
|
||||
for (int i = 0; i < node.ChildNodes.Count; i++)
|
||||
{
|
||||
SerializeNode(writer, node.ChildNodes[i], false);
|
||||
}
|
||||
|
||||
writer.WriteEndConstructor();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
@@ -174,6 +206,11 @@ namespace Newtonsoft.Json.Converters
|
||||
case XmlNodeType.ProcessingInstruction:
|
||||
case XmlNodeType.Whitespace:
|
||||
case XmlNodeType.SignificantWhitespace:
|
||||
if (node.Prefix == "xmlns" && node.Value == JsonNamespaceUri)
|
||||
break;
|
||||
else if (node.NamespaceURI == JsonNamespaceUri)
|
||||
break;
|
||||
|
||||
if (writePropertyName)
|
||||
writer.WritePropertyName(GetPropertyName(node));
|
||||
writer.WriteValue(node.Value);
|
||||
@@ -216,6 +253,10 @@ namespace Newtonsoft.Json.Converters
|
||||
|
||||
XmlDocument document = new XmlDocument();
|
||||
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
|
||||
|
||||
if (reader.TokenType != JsonToken.StartObject)
|
||||
throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object.");
|
||||
|
||||
reader.Read();
|
||||
|
||||
DeserializeNode(reader, document, manager, document);
|
||||
@@ -241,7 +282,7 @@ namespace Newtonsoft.Json.Converters
|
||||
break;
|
||||
default:
|
||||
// processing instructions and the xml declaration start with ?
|
||||
if (propertyName[0] == '?')
|
||||
if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?')
|
||||
{
|
||||
if (propertyName == DeclarationName)
|
||||
{
|
||||
@@ -292,7 +333,8 @@ namespace Newtonsoft.Json.Converters
|
||||
&& reader.TokenType != JsonToken.Boolean
|
||||
&& reader.TokenType != JsonToken.Integer
|
||||
&& reader.TokenType != JsonToken.Float
|
||||
&& reader.TokenType != JsonToken.Date)
|
||||
&& reader.TokenType != JsonToken.Date
|
||||
&& reader.TokenType != JsonToken.StartConstructor)
|
||||
{
|
||||
// read properties until first non-attribute is encountered
|
||||
while (!finishedAttributes && !finishedElement && reader.Read())
|
||||
@@ -370,7 +412,8 @@ namespace Newtonsoft.Json.Converters
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.Date)
|
||||
{
|
||||
element.AppendChild(document.CreateTextNode(XmlConvert.ToString((DateTime)reader.Value)));
|
||||
DateTime d = (DateTime)reader.Value;
|
||||
element.AppendChild(document.CreateTextNode(XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind))));
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
@@ -400,6 +443,9 @@ namespace Newtonsoft.Json.Converters
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null)
|
||||
throw new JsonSerializationException("JSON root object has multiple properties.");
|
||||
|
||||
string propertyName = reader.Value.ToString();
|
||||
reader.Read();
|
||||
|
||||
@@ -415,6 +461,14 @@ namespace Newtonsoft.Json.Converters
|
||||
DeserializeValue(reader, document, manager, propertyName, currentNode);
|
||||
}
|
||||
break;
|
||||
case JsonToken.StartConstructor:
|
||||
string constructorName = reader.Value.ToString();
|
||||
|
||||
while (reader.Read() && reader.TokenType != JsonToken.EndConstructor)
|
||||
{
|
||||
DeserializeValue(reader, document, manager, "-" + constructorName, currentNode);
|
||||
}
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
case JsonToken.EndArray:
|
||||
return;
|
||||
@@ -459,6 +513,16 @@ namespace Newtonsoft.Json.Converters
|
||||
else
|
||||
return qualifiedName.Substring(0, colonPosition);
|
||||
}
|
||||
|
||||
private IEnumerable<XmlAttribute> ValueAttributes(XmlAttributeCollection c)
|
||||
{
|
||||
return c.OfType<XmlAttribute>().Where(a => a.NamespaceURI != JsonNamespaceUri);
|
||||
}
|
||||
|
||||
private IEnumerable<XmlNode> ValueNodes(XmlNodeList c)
|
||||
{
|
||||
return c.OfType<XmlNode>().Where(n => n.NamespaceURI != JsonNamespaceUri);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override bool CanConvert(Type valueType)
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Newtonsoft.Json
|
||||
Null = "null";
|
||||
Undefined = "undefined";
|
||||
|
||||
InitialJavaScriptDateTicks = (new DateTime(1970, 1, 1)).Ticks;
|
||||
InitialJavaScriptDateTicks = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Ticks;
|
||||
MinimumJavaScriptDate = new DateTime(100, 1, 1);
|
||||
}
|
||||
|
||||
@@ -86,24 +86,53 @@ namespace Newtonsoft.Json
|
||||
/// <returns>A Json string representation of the <see cref="DateTime"/>.</returns>
|
||||
public static string ToString(DateTime value)
|
||||
{
|
||||
long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value);
|
||||
|
||||
return "new Date(" + javaScriptTicks + ")";
|
||||
return ToStringInternal(new DateTimeOffset(value), value.Kind);
|
||||
}
|
||||
|
||||
internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
|
||||
/// <summary>
|
||||
/// Converts the <see cref="DateTimeOffset"/> to it's JavaScript string representation.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to convert.</param>
|
||||
/// <returns>A Json string representation of the <see cref="DateTimeOffset"/>.</returns>
|
||||
public static string ToString(DateTimeOffset value)
|
||||
{
|
||||
if (dateTime < MinimumJavaScriptDate)
|
||||
dateTime = MinimumJavaScriptDate;
|
||||
return ToStringInternal(value, DateTimeKind.Local);
|
||||
}
|
||||
|
||||
long javaScriptTicks = (dateTime.Ticks - InitialJavaScriptDateTicks) / (long)10000;
|
||||
public static string ToStringInternal(DateTimeOffset value, DateTimeKind kind)
|
||||
{
|
||||
long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value);
|
||||
|
||||
string offset;
|
||||
switch (kind)
|
||||
{
|
||||
case DateTimeKind.Local:
|
||||
case DateTimeKind.Unspecified:
|
||||
TimeSpan utcOffset = value.Offset;
|
||||
offset = utcOffset.Hours.ToString("+00;-00") + utcOffset.Minutes.ToString("00;00");
|
||||
break;
|
||||
default:
|
||||
offset = string.Empty;
|
||||
break;
|
||||
}
|
||||
return @"""\/Date(" + javaScriptTicks.ToString(CultureInfo.InvariantCulture) + offset + @")\/""";
|
||||
}
|
||||
|
||||
internal static long ConvertDateTimeToJavaScriptTicks(DateTimeOffset dateTime)
|
||||
{
|
||||
DateTimeOffset utcDateTime = dateTime.ToUniversalTime();
|
||||
|
||||
//if (utcDateTime < MinimumJavaScriptDate)
|
||||
// utcDateTime = MinimumJavaScriptDate;
|
||||
|
||||
long javaScriptTicks = (utcDateTime.Ticks - InitialJavaScriptDateTicks) / (long)10000;
|
||||
|
||||
return javaScriptTicks;
|
||||
}
|
||||
|
||||
internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
|
||||
{
|
||||
DateTime dateTime = new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks);
|
||||
DateTime dateTime = new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc);
|
||||
|
||||
return dateTime;
|
||||
}
|
||||
@@ -328,6 +357,10 @@ namespace Newtonsoft.Json
|
||||
return ToString((decimal)convertible);
|
||||
}
|
||||
}
|
||||
else if (value is DateTimeOffset)
|
||||
{
|
||||
return ToString((DateTimeOffset)value);
|
||||
}
|
||||
|
||||
throw new ArgumentException(string.Format("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.", value.GetType()));
|
||||
}
|
||||
@@ -396,13 +429,29 @@ namespace Newtonsoft.Json
|
||||
return DeserializeObject<T>(value, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the specified JSON to the given anonymous type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The anonymous type to deserialize to. This can't be specified
|
||||
/// traditionally and must be infered from the anonymous type passed
|
||||
/// as a parameter.
|
||||
/// </typeparam>
|
||||
/// <param name="value">The object to deserialize.</param>
|
||||
/// <param name="anonymousTypeObject">The anonymous type object.</param>
|
||||
/// <returns>The deserialized anonymous type from the JSON string.</returns>
|
||||
public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
|
||||
{
|
||||
return (T)DeserializeObject(value, typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the specified object to a Json object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
|
||||
/// <param name="value">The object to deserialize.</param>
|
||||
/// <param name="converters">Converters to use while deserializing.</param>
|
||||
/// <returns>The deserialized object from the Json string.</returns>
|
||||
/// <returns>The deserialized object from the JSON string.</returns>
|
||||
public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
|
||||
{
|
||||
return (T)DeserializeObject(value, typeof(T), converters);
|
||||
@@ -438,7 +487,7 @@ namespace Newtonsoft.Json
|
||||
return SerializeObject(node, converter);
|
||||
}
|
||||
|
||||
public static XmlNode DeerializeXmlNode(string value)
|
||||
public static XmlNode DeserializeXmlNode(string value)
|
||||
{
|
||||
XmlNodeConverter converter = new XmlNodeConverter();
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace Newtonsoft.Json
|
||||
|
||||
public virtual object ReadJson(JsonReader reader, Type objectType)
|
||||
{
|
||||
throw new NotImplementedException(string.Format("{0} has not overriden FromJson method.", GetType().Name));
|
||||
throw new NotImplementedException(string.Format("{0} has not overriden the ReadJson method.", GetType().Name));
|
||||
}
|
||||
|
||||
public abstract bool CanConvert(Type objectType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,11 +217,54 @@ namespace Newtonsoft.Json
|
||||
|
||||
ClearCurrentChar();
|
||||
_currentState = State.PostValue;
|
||||
_token = JsonToken.String;
|
||||
_value = _buffer.ToString();
|
||||
string text = _buffer.ToString();
|
||||
_buffer.Position = 0;
|
||||
_valueType = typeof(string);
|
||||
_quoteChar = quote;
|
||||
|
||||
if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
|
||||
{
|
||||
ParseDate(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetToken(JsonToken.String, text);
|
||||
_quoteChar = quote;
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseDate(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);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
kind = DateTimeKind.Local;
|
||||
value = value.Substring(0, index);
|
||||
}
|
||||
|
||||
long javaScriptTicks = long.Parse(value);
|
||||
DateTime utcDateTime = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
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;
|
||||
}
|
||||
|
||||
SetToken(JsonToken.Date, dateTime);
|
||||
}
|
||||
|
||||
private bool MoveNext()
|
||||
@@ -648,22 +691,22 @@ namespace Newtonsoft.Json
|
||||
_value = constructorName;
|
||||
_valueType = typeof(string);
|
||||
|
||||
if (string.CompareOrdinal(constructorName, "Date") == 0)
|
||||
{
|
||||
IList<object> parameters = new List<object>();
|
||||
//if (string.CompareOrdinal(constructorName, "Date") == 0)
|
||||
//{
|
||||
// IList<object> parameters = new List<object>();
|
||||
|
||||
MoveNext();
|
||||
while (ParseValue() && _token != JsonToken.EndConstructor)
|
||||
{
|
||||
parameters.Add(_value);
|
||||
}
|
||||
// MoveNext();
|
||||
// while (ParseValue() && _token != JsonToken.EndConstructor)
|
||||
// {
|
||||
// parameters.Add(_value);
|
||||
// }
|
||||
|
||||
long javaScriptTicks = Convert.ToInt64(parameters[0]);
|
||||
// long javaScriptTicks = Convert.ToInt64(parameters[0]);
|
||||
|
||||
DateTime date = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
// DateTime date = JavaScriptConvert.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
|
||||
|
||||
SetToken(JsonToken.Date, date);
|
||||
}
|
||||
// SetToken(JsonToken.Date, date);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
@@ -754,6 +797,9 @@ namespace Newtonsoft.Json
|
||||
case JsonType.Array:
|
||||
_currentState = State.Array;
|
||||
break;
|
||||
case JsonType.Constructor:
|
||||
_currentState = State.Constructor;
|
||||
break;
|
||||
case JsonType.None:
|
||||
_currentState = State.Finished;
|
||||
break;
|
||||
|
||||
@@ -32,6 +32,7 @@ using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
using Newtonsoft.Json.Utilities;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Newtonsoft.Json
|
||||
{
|
||||
@@ -233,11 +234,7 @@ namespace Newtonsoft.Json
|
||||
case JsonToken.EndConstructor:
|
||||
string constructorName = reader.Value.ToString();
|
||||
|
||||
//if (string.CompareOrdinal(constructorName, "Date") == 0)
|
||||
// value = CreateDate(reader);
|
||||
//else
|
||||
//TODO: use objectType plus constructor arguments to instantiate object
|
||||
value = constructorName;
|
||||
value = constructorName;
|
||||
break;
|
||||
case JsonToken.Null:
|
||||
case JsonToken.Undefined:
|
||||
@@ -298,12 +295,15 @@ namespace Newtonsoft.Json
|
||||
return targetConverter.ConvertFromInvariantString(valueString);
|
||||
}
|
||||
|
||||
if (targetType == typeof(DateTimeOffset) && value is DateTime)
|
||||
return new DateTimeOffset((DateTime)value);
|
||||
|
||||
if (!targetType.IsAssignableFrom(valueType))
|
||||
throw new InvalidOperationException(string.Format("Cannot convert object of type '{0}' to type '{1}'", value.GetType(), targetType));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
return targetConverter.ConvertFrom(null, CultureInfo.InvariantCulture, value);
|
||||
}
|
||||
else
|
||||
@@ -343,7 +343,7 @@ namespace Newtonsoft.Json
|
||||
else
|
||||
mappedName = member.Name;
|
||||
|
||||
bool ignored = member.IsDefined(typeof (JsonIgnoreAttribute), true);
|
||||
bool ignored = member.IsDefined(typeof(JsonIgnoreAttribute), true);
|
||||
bool readable = ReflectionUtils.CanReadMemberValue(member);
|
||||
bool writable = ReflectionUtils.CanSetMemberValue(member);
|
||||
MemberMapping memberMapping = new MemberMapping(mappedName, member, ignored, readable, writable);
|
||||
@@ -409,50 +409,102 @@ namespace Newtonsoft.Json
|
||||
Type elementType = ReflectionUtils.GetListItemType(objectType);
|
||||
|
||||
IList populatedList = CollectionUtils.CreateAndPopulateList(objectType, delegate(IList list)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
while (reader.Read())
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.EndArray:
|
||||
return;
|
||||
case JsonToken.Comment:
|
||||
break;
|
||||
default:
|
||||
object value = GetObject(reader, elementType);
|
||||
case JsonToken.EndArray:
|
||||
return;
|
||||
case JsonToken.Comment:
|
||||
break;
|
||||
default:
|
||||
object value = GetObject(reader, elementType);
|
||||
|
||||
list.Add(value);
|
||||
break;
|
||||
}
|
||||
list.Add(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonSerializationException("Unexpected end when deserializing array.");
|
||||
});
|
||||
throw new JsonSerializationException("Unexpected end when deserializing array.");
|
||||
});
|
||||
|
||||
return populatedList;
|
||||
}
|
||||
|
||||
private object PopulateObject(JsonReader reader, Type objectType)
|
||||
{
|
||||
object newObject = Activator.CreateInstance(objectType);
|
||||
object newObject;
|
||||
|
||||
while (reader.Read())
|
||||
if (ReflectionUtils.HasDefaultConstructor(objectType))
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
newObject = Activator.CreateInstance(objectType);
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
string memberName = reader.Value.ToString();
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
string memberName = reader.Value.ToString();
|
||||
|
||||
SetObjectMember(reader, newObject, objectType, memberName);
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
return newObject;
|
||||
default:
|
||||
throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
|
||||
SetObjectMember(reader, newObject, objectType, memberName);
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
return newObject;
|
||||
default:
|
||||
throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonSerializationException("Unexpected end when deserializing object.");
|
||||
throw new JsonSerializationException("Unexpected end when deserializing object.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ConstructorInfo c = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault();
|
||||
|
||||
if (c == null)
|
||||
throw new Exception("sdsdf");
|
||||
|
||||
IDictionary<ParameterInfo, object> constructorParameters = c.GetParameters().ToDictionary(p => p, p => (object)null);
|
||||
//IList<object> constructorValues
|
||||
|
||||
bool exit = false;
|
||||
while (!exit && reader.Read())
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.PropertyName:
|
||||
string memberName = reader.Value.ToString();
|
||||
ParameterInfo matchingConstructorParameter = constructorParameters
|
||||
.Where(kv => kv.Key.Name == memberName)
|
||||
.Select(kv => kv.Key)
|
||||
.SingleOrDefault();
|
||||
|
||||
if (!reader.Read())
|
||||
throw new JsonSerializationException(string.Format("Unexpected end when setting {0}'s value.", memberName));
|
||||
|
||||
|
||||
if (matchingConstructorParameter != null)
|
||||
{
|
||||
constructorParameters[matchingConstructorParameter] = GetObject(reader, matchingConstructorParameter.ParameterType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//SetObjectMember(reader, newObject, objectType, memberName);
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
exit = true;
|
||||
break;
|
||||
default:
|
||||
throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
|
||||
}
|
||||
}
|
||||
|
||||
newObject = Activator.CreateInstance(objectType, constructorParameters.Values.ToArray());
|
||||
|
||||
return newObject;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -554,6 +606,10 @@ namespace Newtonsoft.Json
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (value is DateTimeOffset)
|
||||
{
|
||||
writer.WriteValue((DateTimeOffset)value);
|
||||
}
|
||||
else if (value is IList)
|
||||
{
|
||||
SerializeList(writer, (IList)value);
|
||||
@@ -694,4 +750,4 @@ namespace Newtonsoft.Json
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -724,6 +724,15 @@ namespace Newtonsoft.Json
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Date);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <see cref="DateTimeOffset"/> value.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
|
||||
public void WriteValue(DateTimeOffset value)
|
||||
{
|
||||
WriteValueInternal(JavaScriptConvert.ToString(value), JsonToken.Date);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -73,7 +73,9 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Converters\AspNetAjaxDateTimeConverter.cs" />
|
||||
<Compile Include="Converters\IsoDateTimeConverter.cs" />
|
||||
<Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
|
||||
<Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
|
||||
<Compile Include="Converters\XmlNodeConverter.cs" />
|
||||
<Compile Include="Converters\HtmlColorConverter.cs" />
|
||||
<Compile Include="JavaScriptParameters.cs" />
|
||||
@@ -105,6 +107,7 @@
|
||||
<Compile Include="MissingMemberHandling.cs" />
|
||||
<Compile Include="NullValueHandling.cs" />
|
||||
<Compile Include="ReferenceLoopHandling.cs" />
|
||||
<Compile Include="Utilities\DateTimeUtils.cs" />
|
||||
<Compile Include="Utilities\JavaScriptUtils.cs" />
|
||||
<Compile Include="JsonToken.cs" />
|
||||
<Compile Include="JsonWriter.cs" />
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
public static class DateTimeUtils
|
||||
{
|
||||
public static string GetLocalOffset(this DateTime d)
|
||||
{
|
||||
TimeSpan utcOffset = TimeZoneInfo.Local.GetUtcOffset(d);
|
||||
|
||||
return utcOffset.Hours.ToString("+00;-00") + ":" + utcOffset.Minutes.ToString("00;00");
|
||||
}
|
||||
|
||||
public static XmlDateTimeSerializationMode ToSerializationMode(DateTimeKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case DateTimeKind.Local:
|
||||
return XmlDateTimeSerializationMode.Local;
|
||||
case DateTimeKind.Unspecified:
|
||||
return XmlDateTimeSerializationMode.Unspecified;
|
||||
case DateTimeKind.Utc:
|
||||
return XmlDateTimeSerializationMode.Utc;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("kind", kind, "Unexpected DateTimeKind value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,4 +545,4 @@ namespace Newtonsoft.Json.Utilities
|
||||
return Activator.CreateInstance(specificType, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user