-Fixed Path on JsonValidatingReader -Fixed path queries over constructors
5532 lines
176 KiB
C#
5532 lines
176 KiB
C#
#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;
|
|
#if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE)
|
|
using System.Collections.Concurrent;
|
|
#endif
|
|
using System.Collections.Generic;
|
|
#if !SILVERLIGHT && !PocketPC && !NET20
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Configuration;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.Serialization.Formatters;
|
|
using System.Threading;
|
|
using System.Web.Script.Serialization;
|
|
#endif
|
|
using System.Text;
|
|
using NUnit.Framework;
|
|
using Newtonsoft.Json;
|
|
using System.IO;
|
|
using System.Collections;
|
|
using System.Xml;
|
|
using System.Xml.Serialization;
|
|
using System.Collections.ObjectModel;
|
|
using Newtonsoft.Json.Bson;
|
|
using Newtonsoft.Json.Linq;
|
|
using System.Linq;
|
|
using Newtonsoft.Json.Converters;
|
|
#if !PocketPC && !NET20 && !WINDOWS_PHONE
|
|
using System.Runtime.Serialization.Json;
|
|
#endif
|
|
using Newtonsoft.Json.Tests.TestObjects;
|
|
using System.Runtime.Serialization;
|
|
using System.Globalization;
|
|
using Newtonsoft.Json.Utilities;
|
|
using System.Reflection;
|
|
#if !NET20 && !SILVERLIGHT
|
|
using System.Xml.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Collections.Specialized;
|
|
using System.Linq.Expressions;
|
|
#endif
|
|
#if !(NET35 || NET20 || WINDOWS_PHONE)
|
|
using System.Dynamic;
|
|
using System.ComponentModel;
|
|
#endif
|
|
|
|
namespace Newtonsoft.Json.Tests.Serialization
|
|
{
|
|
public class JsonSerializerTest : TestFixtureBase
|
|
{
|
|
[Test]
|
|
public void PersonTypedObjectDeserialization()
|
|
{
|
|
Store store = new Store();
|
|
|
|
string jsonText = JsonConvert.SerializeObject(store);
|
|
|
|
Store deserializedStore = (Store) JsonConvert.DeserializeObject(jsonText, typeof (Store));
|
|
|
|
Assert.AreEqual(store.Establised, deserializedStore.Establised);
|
|
Assert.AreEqual(store.product.Count, deserializedStore.product.Count);
|
|
|
|
Console.WriteLine(jsonText);
|
|
}
|
|
|
|
[Test]
|
|
public void TypedObjectDeserialization()
|
|
{
|
|
Product product = new Product();
|
|
|
|
product.Name = "Apple";
|
|
product.ExpiryDate = new DateTime(2008, 12, 28);
|
|
product.Price = 3.99M;
|
|
product.Sizes = new string[] {"Small", "Medium", "Large"};
|
|
|
|
string output = JsonConvert.SerializeObject(product);
|
|
//{
|
|
// "Name": "Apple",
|
|
// "ExpiryDate": "\/Date(1230375600000+1300)\/",
|
|
// "Price": 3.99,
|
|
// "Sizes": [
|
|
// "Small",
|
|
// "Medium",
|
|
// "Large"
|
|
// ]
|
|
//}
|
|
|
|
Product deserializedProduct = (Product) JsonConvert.DeserializeObject(output, typeof (Product));
|
|
|
|
Assert.AreEqual("Apple", deserializedProduct.Name);
|
|
Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate);
|
|
Assert.AreEqual(3.99, deserializedProduct.Price);
|
|
Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
|
|
Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
|
|
Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
|
|
}
|
|
|
|
//[Test]
|
|
//public void Advanced()
|
|
//{
|
|
// Product product = new Product();
|
|
// product.ExpiryDate = new DateTime(2008, 12, 28);
|
|
|
|
// JsonSerializer serializer = new JsonSerializer();
|
|
// serializer.Converters.Add(new JavaScriptDateTimeConverter());
|
|
// serializer.NullValueHandling = NullValueHandling.Ignore;
|
|
|
|
// using (StreamWriter sw = new StreamWriter(@"c:\json.txt"))
|
|
// using (JsonWriter writer = new JsonTextWriter(sw))
|
|
// {
|
|
// serializer.Serialize(writer, product);
|
|
// // {"ExpiryDate":new Date(1230375600000),"Price":0}
|
|
// }
|
|
//}
|
|
|
|
[Test]
|
|
public void JsonConvertSerializer()
|
|
{
|
|
string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
|
|
|
|
Product p = JsonConvert.DeserializeObject(value, typeof (Product)) as Product;
|
|
|
|
Assert.AreEqual("Orange", p.Name);
|
|
Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.ExpiryDate);
|
|
Assert.AreEqual(3.99, p.Price);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeJavaScriptDate()
|
|
{
|
|
DateTime dateValue = new DateTime(2010, 3, 30);
|
|
Dictionary<string, object> testDictionary = new Dictionary<string, object>();
|
|
testDictionary["date"] = dateValue;
|
|
|
|
string jsonText = JsonConvert.SerializeObject(testDictionary);
|
|
|
|
#if !PocketPC && !NET20 && !WINDOWS_PHONE
|
|
MemoryStream ms = new MemoryStream();
|
|
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (Dictionary<string, object>));
|
|
serializer.WriteObject(ms, testDictionary);
|
|
|
|
byte[] data = ms.ToArray();
|
|
string output = Encoding.UTF8.GetString(data, 0, data.Length);
|
|
#endif
|
|
|
|
Dictionary<string, object> deserializedDictionary = (Dictionary<string, object>) JsonConvert.DeserializeObject(jsonText, typeof (Dictionary<string, object>));
|
|
DateTime deserializedDate = (DateTime) deserializedDictionary["date"];
|
|
|
|
Assert.AreEqual(dateValue, deserializedDate);
|
|
|
|
Console.WriteLine("DeserializeJavaScriptDate");
|
|
Console.WriteLine(jsonText);
|
|
Console.WriteLine();
|
|
Console.WriteLine(jsonText);
|
|
}
|
|
|
|
[Test]
|
|
public void TestMethodExecutorObject()
|
|
{
|
|
MethodExecutorObject executorObject = new MethodExecutorObject();
|
|
executorObject.serverClassName = "BanSubs";
|
|
executorObject.serverMethodParams = new object[] {"21321546", "101", "1236", "D:\\1.txt"};
|
|
executorObject.clientGetResultFunction = "ClientBanSubsCB";
|
|
|
|
string output = JsonConvert.SerializeObject(executorObject);
|
|
|
|
MethodExecutorObject executorObject2 = JsonConvert.DeserializeObject(output, typeof (MethodExecutorObject)) as MethodExecutorObject;
|
|
|
|
Assert.AreNotSame(executorObject, executorObject2);
|
|
Assert.AreEqual(executorObject2.serverClassName, "BanSubs");
|
|
Assert.AreEqual(executorObject2.serverMethodParams.Length, 4);
|
|
Assert.Contains("101", executorObject2.serverMethodParams);
|
|
Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB");
|
|
}
|
|
|
|
#if !SILVERLIGHT
|
|
[Test]
|
|
public void HashtableDeserialization()
|
|
{
|
|
string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
|
|
|
|
Hashtable p = JsonConvert.DeserializeObject(value, typeof (Hashtable)) as Hashtable;
|
|
|
|
Assert.AreEqual("Orange", p["Name"].ToString());
|
|
}
|
|
|
|
[Test]
|
|
public void TypedHashtableDeserialization()
|
|
{
|
|
string value = @"{""Name"":""Orange"", ""Hash"":{""ExpiryDate"":""01/24/2010 12:00:00"",""UntypedArray"":[""01/24/2010 12:00:00""]}}";
|
|
|
|
TypedSubHashtable p = JsonConvert.DeserializeObject(value, typeof (TypedSubHashtable)) as TypedSubHashtable;
|
|
|
|
Assert.AreEqual("01/24/2010 12:00:00", p.Hash["ExpiryDate"].ToString());
|
|
Assert.AreEqual(@"[
|
|
""01/24/2010 12:00:00""
|
|
]", p.Hash["UntypedArray"].ToString());
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void SerializeDeserializeGetOnlyProperty()
|
|
{
|
|
string value = JsonConvert.SerializeObject(new GetOnlyPropertyClass());
|
|
|
|
GetOnlyPropertyClass c = JsonConvert.DeserializeObject<GetOnlyPropertyClass>(value);
|
|
|
|
Assert.AreEqual(c.Field, "Field");
|
|
Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty");
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeDeserializeSetOnlyProperty()
|
|
{
|
|
string value = JsonConvert.SerializeObject(new SetOnlyPropertyClass());
|
|
|
|
SetOnlyPropertyClass c = JsonConvert.DeserializeObject<SetOnlyPropertyClass>(value);
|
|
|
|
Assert.AreEqual(c.Field, "Field");
|
|
}
|
|
|
|
[Test]
|
|
public void JsonIgnoreAttributeTest()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeTestClass());
|
|
|
|
Assert.AreEqual(@"{""Field"":0,""Property"":21}", json);
|
|
|
|
JsonIgnoreAttributeTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeTestClass>(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1,""IgnoredObject"":[1,2,3,4,5]}");
|
|
|
|
Assert.AreEqual(0, c.IgnoredField);
|
|
Assert.AreEqual(99, c.Field);
|
|
}
|
|
|
|
[Test]
|
|
public void GoogleSearchAPI()
|
|
{
|
|
string json = @"{
|
|
results:
|
|
[
|
|
{
|
|
GsearchResultClass:""GwebSearch"",
|
|
unescapedUrl : ""http://www.google.com/"",
|
|
url : ""http://www.google.com/"",
|
|
visibleUrl : ""www.google.com"",
|
|
cacheUrl :
|
|
""http://www.google.com/search?q=cache:zhool8dxBV4J:www.google.com"",
|
|
title : ""Google"",
|
|
titleNoFormatting : ""Google"",
|
|
content : ""Enables users to search the Web, Usenet, and
|
|
images. Features include PageRank, caching and translation of
|
|
results, and an option to find similar pages.""
|
|
},
|
|
{
|
|
GsearchResultClass:""GwebSearch"",
|
|
unescapedUrl : ""http://news.google.com/"",
|
|
url : ""http://news.google.com/"",
|
|
visibleUrl : ""news.google.com"",
|
|
cacheUrl :
|
|
""http://www.google.com/search?q=cache:Va_XShOz_twJ:news.google.com"",
|
|
title : ""Google News"",
|
|
titleNoFormatting : ""Google News"",
|
|
content : ""Aggregated headlines and a search engine of many of the world's news sources.""
|
|
},
|
|
|
|
{
|
|
GsearchResultClass:""GwebSearch"",
|
|
unescapedUrl : ""http://groups.google.com/"",
|
|
url : ""http://groups.google.com/"",
|
|
visibleUrl : ""groups.google.com"",
|
|
cacheUrl :
|
|
""http://www.google.com/search?q=cache:x2uPD3hfkn0J:groups.google.com"",
|
|
title : ""Google Groups"",
|
|
titleNoFormatting : ""Google Groups"",
|
|
content : ""Enables users to search and browse the Usenet
|
|
archives which consist of over 700 million messages, and post new
|
|
comments.""
|
|
},
|
|
|
|
{
|
|
GsearchResultClass:""GwebSearch"",
|
|
unescapedUrl : ""http://maps.google.com/"",
|
|
url : ""http://maps.google.com/"",
|
|
visibleUrl : ""maps.google.com"",
|
|
cacheUrl :
|
|
""http://www.google.com/search?q=cache:dkf5u2twBXIJ:maps.google.com"",
|
|
title : ""Google Maps"",
|
|
titleNoFormatting : ""Google Maps"",
|
|
content : ""Provides directions, interactive maps, and
|
|
satellite/aerial imagery of the United States. Can also search by
|
|
keyword such as type of business.""
|
|
}
|
|
],
|
|
|
|
adResults:
|
|
[
|
|
{
|
|
GsearchResultClass:""GwebSearch.ad"",
|
|
title : ""Gartner Symposium/ITxpo"",
|
|
content1 : ""Meet brilliant Gartner IT analysts"",
|
|
content2 : ""20-23 May 2007- Barcelona, Spain"",
|
|
url :
|
|
""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="",
|
|
|
|
impressionUrl :
|
|
""http://www.google.com/uds/css/ad-indicator-on.gif?ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB"",
|
|
|
|
unescapedUrl :
|
|
""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="",
|
|
|
|
visibleUrl : ""www.gartner.com""
|
|
}
|
|
]
|
|
}
|
|
";
|
|
object o = JsonConvert.DeserializeObject(json);
|
|
string s = string.Empty;
|
|
s += s;
|
|
}
|
|
|
|
[Test]
|
|
public void TorrentDeserializeTest()
|
|
{
|
|
string jsonText = @"{
|
|
"""":"""",
|
|
""label"": [
|
|
[""SomeName"",6]
|
|
],
|
|
""torrents"": [
|
|
[""192D99A5C943555CB7F00A852821CF6D6DB3008A"",201,""filename.avi"",178311826,1000,178311826,72815250,408,1603,7,121430,""NameOfLabelPrevioslyDefined"",3,6,0,8,128954,-1,0],
|
|
],
|
|
""torrentc"": ""1816000723""
|
|
}";
|
|
|
|
JObject o = (JObject) JsonConvert.DeserializeObject(jsonText);
|
|
Assert.AreEqual(4, o.Children().Count());
|
|
|
|
JToken torrentsArray = (JToken) o["torrents"];
|
|
JToken nestedTorrentsArray = (JToken) torrentsArray[0];
|
|
Assert.AreEqual(nestedTorrentsArray.Children().Count(), 19);
|
|
}
|
|
|
|
[Test]
|
|
public void JsonPropertyClassSerialize()
|
|
{
|
|
JsonPropertyClass test = new JsonPropertyClass();
|
|
test.Pie = "Delicious";
|
|
test.SweetCakesCount = int.MaxValue;
|
|
|
|
string jsonText = JsonConvert.SerializeObject(test);
|
|
|
|
Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText);
|
|
|
|
JsonPropertyClass test2 = JsonConvert.DeserializeObject<JsonPropertyClass>(jsonText);
|
|
|
|
Assert.AreEqual(test.Pie, test2.Pie);
|
|
Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.")]
|
|
public void BadJsonPropertyClassSerialize()
|
|
{
|
|
JsonConvert.SerializeObject(new BadJsonPropertyClass());
|
|
}
|
|
|
|
[Test]
|
|
public void InheritedListSerialize()
|
|
{
|
|
Article a1 = new Article("a1");
|
|
Article a2 = new Article("a2");
|
|
|
|
ArticleCollection articles1 = new ArticleCollection();
|
|
articles1.Add(a1);
|
|
articles1.Add(a2);
|
|
|
|
string jsonText = JsonConvert.SerializeObject(articles1);
|
|
|
|
ArticleCollection articles2 = JsonConvert.DeserializeObject<ArticleCollection>(jsonText);
|
|
|
|
Assert.AreEqual(articles1.Count, articles2.Count);
|
|
Assert.AreEqual(articles1[0].Name, articles2[0].Name);
|
|
}
|
|
|
|
[Test]
|
|
public void ReadOnlyCollectionSerialize()
|
|
{
|
|
ReadOnlyCollection<int> r1 = new ReadOnlyCollection<int>(new int[] {0, 1, 2, 3, 4});
|
|
|
|
string jsonText = JsonConvert.SerializeObject(r1);
|
|
|
|
ReadOnlyCollection<int> r2 = JsonConvert.DeserializeObject<ReadOnlyCollection<int>>(jsonText);
|
|
|
|
CollectionAssert.AreEqual(r1, r2);
|
|
}
|
|
|
|
#if !PocketPC && !NET20 && !WINDOWS_PHONE
|
|
[Test]
|
|
public void Unicode()
|
|
{
|
|
string json = @"[""PRE\u003cPOST""]";
|
|
|
|
DataContractJsonSerializer s = new DataContractJsonSerializer(typeof (List<string>));
|
|
List<string> dataContractResult = (List<string>) s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
|
|
|
|
List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
|
|
|
|
Assert.AreEqual(1, jsonNetResult.Count);
|
|
Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void BackslashEqivilence()
|
|
{
|
|
string json = @"[""vvv\/vvv\tvvv\""vvv\bvvv\nvvv\rvvv\\vvv\fvvv""]";
|
|
|
|
#if !SILVERLIGHT
|
|
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
|
|
List<string> javaScriptSerializerResult = javaScriptSerializer.Deserialize<List<string>>(json);
|
|
#endif
|
|
|
|
DataContractJsonSerializer s = new DataContractJsonSerializer(typeof (List<string>));
|
|
List<string> dataContractResult = (List<string>) s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
|
|
|
|
List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
|
|
|
|
Assert.AreEqual(1, jsonNetResult.Count);
|
|
Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
|
|
#if !SILVERLIGHT
|
|
Assert.AreEqual(javaScriptSerializerResult[0], jsonNetResult[0]);
|
|
#endif
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonReaderException), ExpectedMessage = @"Bad JSON escape sequence: \j. Line 1, position 7.")]
|
|
public void InvalidBackslash()
|
|
{
|
|
string json = @"[""vvv\jvvv""]";
|
|
|
|
JsonConvert.DeserializeObject<List<string>>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void DateTimeTest()
|
|
{
|
|
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 = JsonConvert.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 = JsonConvert.SerializeObject(testDates);
|
|
Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result);
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void NonStringKeyDictionary()
|
|
{
|
|
Dictionary<int, int> values = new Dictionary<int, int>();
|
|
values.Add(-5, 6);
|
|
values.Add(int.MinValue, int.MaxValue);
|
|
|
|
string json = JsonConvert.SerializeObject(values);
|
|
|
|
Assert.AreEqual(@"{""-5"":6,""-2147483648"":2147483647}", json);
|
|
|
|
Dictionary<int, int> newValues = JsonConvert.DeserializeObject<Dictionary<int, int>>(json);
|
|
|
|
CollectionAssert.AreEqual(values, newValues);
|
|
}
|
|
|
|
[Test]
|
|
public void AnonymousObjectSerialization()
|
|
{
|
|
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 = JsonConvert.SerializeObject(anonymous);
|
|
Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647,""NestedAnonymous"":{""NestedValue"":255},""NestedArray"":[1,2],""Product"":{""Name"":""TestProduct"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null}}", json);
|
|
|
|
anonymous = JsonConvert.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]
|
|
public void CustomCollectionSerialization()
|
|
{
|
|
ProductCollection collection = new ProductCollection()
|
|
{
|
|
new Product() {Name = "Test1"},
|
|
new Product() {Name = "Test2"},
|
|
new Product() {Name = "Test3"}
|
|
};
|
|
|
|
JsonSerializer jsonSerializer = new JsonSerializer();
|
|
jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
|
|
|
|
StringWriter sw = new StringWriter();
|
|
|
|
jsonSerializer.Serialize(sw, collection);
|
|
|
|
Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null}]",
|
|
sw.GetStringBuilder().ToString());
|
|
|
|
ProductCollection collectionNew = (ProductCollection) jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof (ProductCollection));
|
|
|
|
CollectionAssert.AreEqual(collection, collectionNew);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeObject()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new object());
|
|
Assert.AreEqual("{}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeNull()
|
|
{
|
|
string json = JsonConvert.SerializeObject(null);
|
|
Assert.AreEqual("null", json);
|
|
}
|
|
|
|
[Test]
|
|
public void CanDeserializeIntArrayWhenNotFirstPropertyInJson()
|
|
{
|
|
string json = "{foo:'hello',bar:[1,2,3]}";
|
|
ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
|
|
Assert.AreEqual("hello", wibble.Foo);
|
|
|
|
Assert.AreEqual(4, wibble.Bar.Count);
|
|
Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
|
|
Assert.AreEqual(1, wibble.Bar[1]);
|
|
Assert.AreEqual(2, wibble.Bar[2]);
|
|
Assert.AreEqual(3, wibble.Bar[3]);
|
|
}
|
|
|
|
[Test]
|
|
public void CanDeserializeIntArray_WhenArrayIsFirstPropertyInJson()
|
|
{
|
|
string json = "{bar:[1,2,3], foo:'hello'}";
|
|
ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
|
|
Assert.AreEqual("hello", wibble.Foo);
|
|
|
|
Assert.AreEqual(4, wibble.Bar.Count);
|
|
Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
|
|
Assert.AreEqual(1, wibble.Bar[1]);
|
|
Assert.AreEqual(2, wibble.Bar[2]);
|
|
Assert.AreEqual(3, wibble.Bar[3]);
|
|
}
|
|
|
|
[Test]
|
|
public void ObjectCreationHandlingReplace()
|
|
{
|
|
string json = "{bar:[1,2,3], foo:'hello'}";
|
|
|
|
JsonSerializer s = new JsonSerializer();
|
|
s.ObjectCreationHandling = ObjectCreationHandling.Replace;
|
|
|
|
ClassWithArray wibble = (ClassWithArray) s.Deserialize(new StringReader(json), typeof (ClassWithArray));
|
|
|
|
Assert.AreEqual("hello", wibble.Foo);
|
|
|
|
Assert.AreEqual(1, wibble.Bar.Count);
|
|
}
|
|
|
|
[Test]
|
|
public void CanDeserializeSerializedJson()
|
|
{
|
|
ClassWithArray wibble = new ClassWithArray();
|
|
wibble.Foo = "hello";
|
|
wibble.Bar.Add(1);
|
|
wibble.Bar.Add(2);
|
|
wibble.Bar.Add(3);
|
|
string json = JsonConvert.SerializeObject(wibble);
|
|
|
|
ClassWithArray wibbleOut = JsonConvert.DeserializeObject<ClassWithArray>(json);
|
|
Assert.AreEqual("hello", wibbleOut.Foo);
|
|
|
|
Assert.AreEqual(5, wibbleOut.Bar.Count);
|
|
Assert.AreEqual(int.MaxValue, wibbleOut.Bar[0]);
|
|
Assert.AreEqual(int.MaxValue, wibbleOut.Bar[1]);
|
|
Assert.AreEqual(1, wibbleOut.Bar[2]);
|
|
Assert.AreEqual(2, wibbleOut.Bar[3]);
|
|
Assert.AreEqual(3, wibbleOut.Bar[4]);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeConverableObjects()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new ConverableMembers());
|
|
|
|
Assert.AreEqual(@"{""String"":""string"",""Int32"":2147483647,""UInt32"":4294967295,""Byte"":255,""SByte"":127,""Short"":32767,""UShort"":65535,""Long"":9223372036854775807,""ULong"":9223372036854775807,""Double"":1.7976931348623157E+308,""Float"":3.40282347E+38,""DBNull"":null,""Bool"":true,""Char"":""\u0000""}", json);
|
|
|
|
ConverableMembers c = JsonConvert.DeserializeObject<ConverableMembers>(json);
|
|
Assert.AreEqual("string", c.String);
|
|
Assert.AreEqual(double.MaxValue, c.Double);
|
|
Assert.AreEqual(DBNull.Value, c.DBNull);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeStack()
|
|
{
|
|
Stack<object> s = new Stack<object>();
|
|
s.Push(1);
|
|
s.Push(2);
|
|
s.Push(3);
|
|
|
|
string json = JsonConvert.SerializeObject(s);
|
|
Assert.AreEqual("[3,2,1]", json);
|
|
}
|
|
|
|
[Test]
|
|
public void GuidTest()
|
|
{
|
|
Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D");
|
|
|
|
string json = JsonConvert.SerializeObject(new ClassWithGuid {GuidField = guid});
|
|
Assert.AreEqual(@"{""GuidField"":""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""}", json);
|
|
|
|
ClassWithGuid c = JsonConvert.DeserializeObject<ClassWithGuid>(json);
|
|
Assert.AreEqual(guid, c.GuidField);
|
|
}
|
|
|
|
[Test]
|
|
public void EnumTest()
|
|
{
|
|
string json = JsonConvert.SerializeObject(StringComparison.CurrentCultureIgnoreCase);
|
|
Assert.AreEqual(@"1", json);
|
|
|
|
StringComparison s = JsonConvert.DeserializeObject<StringComparison>(json);
|
|
Assert.AreEqual(StringComparison.CurrentCultureIgnoreCase, s);
|
|
}
|
|
|
|
public class ClassWithTimeSpan
|
|
{
|
|
public TimeSpan TimeSpanField;
|
|
}
|
|
|
|
[Test]
|
|
public void TimeSpanTest()
|
|
{
|
|
TimeSpan ts = new TimeSpan(00, 23, 59, 1);
|
|
|
|
string json = JsonConvert.SerializeObject(new ClassWithTimeSpan {TimeSpanField = ts}, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""TimeSpanField"": ""23:59:01""
|
|
}", json);
|
|
|
|
ClassWithTimeSpan c = JsonConvert.DeserializeObject<ClassWithTimeSpan>(json);
|
|
Assert.AreEqual(ts, c.TimeSpanField);
|
|
}
|
|
|
|
[Test]
|
|
public void JsonIgnoreAttributeOnClassTest()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeOnClassTestClass());
|
|
|
|
Assert.AreEqual(@"{""TheField"":0,""Property"":21}", json);
|
|
|
|
JsonIgnoreAttributeOnClassTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeOnClassTestClass>(@"{""TheField"":99,""Property"":-1,""IgnoredField"":-1}");
|
|
|
|
Assert.AreEqual(0, c.IgnoredField);
|
|
Assert.AreEqual(99, c.Field);
|
|
}
|
|
|
|
#if !SILVERLIGHT
|
|
[Test]
|
|
public void SerializeArrayAsArrayList()
|
|
{
|
|
string jsonText = @"[3, ""somestring"",[1,2,3],{}]";
|
|
ArrayList o = JsonConvert.DeserializeObject<ArrayList>(jsonText);
|
|
|
|
Assert.AreEqual(4, o.Count);
|
|
Assert.AreEqual(3, ((JArray) o[2]).Count);
|
|
Assert.AreEqual(0, ((JObject) o[3]).Count);
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void SerializeMemberGenericList()
|
|
{
|
|
Name name = new Name("The Idiot in Next To Me");
|
|
|
|
PhoneNumber p1 = new PhoneNumber("555-1212");
|
|
PhoneNumber p2 = new PhoneNumber("444-1212");
|
|
|
|
name.pNumbers.Add(p1);
|
|
name.pNumbers.Add(p2);
|
|
|
|
string json = JsonConvert.SerializeObject(name, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""personsName"": ""The Idiot in Next To Me"",
|
|
""pNumbers"": [
|
|
{
|
|
""phoneNumber"": ""555-1212""
|
|
},
|
|
{
|
|
""phoneNumber"": ""444-1212""
|
|
}
|
|
]
|
|
}", json);
|
|
|
|
Name newName = JsonConvert.DeserializeObject<Name>(json);
|
|
|
|
Assert.AreEqual("The Idiot in Next To Me", newName.personsName);
|
|
|
|
// not passed in as part of the constructor but assigned to pNumbers property
|
|
Assert.AreEqual(2, newName.pNumbers.Count);
|
|
Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber);
|
|
Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber);
|
|
}
|
|
|
|
[Test]
|
|
public void ConstructorCaseSensitivity()
|
|
{
|
|
ConstructorCaseSensitivityClass c = new ConstructorCaseSensitivityClass("param1", "Param1", "Param2");
|
|
|
|
string json = JsonConvert.SerializeObject(c);
|
|
|
|
ConstructorCaseSensitivityClass deserialized = JsonConvert.DeserializeObject<ConstructorCaseSensitivityClass>(json);
|
|
|
|
Assert.AreEqual("param1", deserialized.param1);
|
|
Assert.AreEqual("Param1", deserialized.Param1);
|
|
Assert.AreEqual("Param2", deserialized.Param2);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializerShouldUseClassConverter()
|
|
{
|
|
ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
|
|
|
|
string json = JsonConvert.SerializeObject(c1);
|
|
Assert.AreEqual(@"[""Class"",""!Test!""]", json);
|
|
|
|
ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json);
|
|
|
|
Assert.AreEqual("!Test!", c2.TestValue);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializerShouldUseClassConverterOverArgumentConverter()
|
|
{
|
|
ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
|
|
|
|
string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
|
|
Assert.AreEqual(@"[""Class"",""!Test!""]", json);
|
|
|
|
ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json, new ArgumentConverterPrecedenceClassConverter());
|
|
|
|
Assert.AreEqual("!Test!", c2.TestValue);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializerShouldUseMemberConverter()
|
|
{
|
|
DateTime testDate = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
|
|
MemberConverterClass m1 = new MemberConverterClass {DefaultConverter = testDate, MemberConverter = testDate};
|
|
|
|
string json = JsonConvert.SerializeObject(m1);
|
|
Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
|
|
|
|
MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
|
|
|
|
Assert.AreEqual(testDate, m2.DefaultConverter);
|
|
Assert.AreEqual(testDate, m2.MemberConverter);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializerShouldUseMemberConverterOverArgumentConverter()
|
|
{
|
|
DateTime testDate = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
|
|
MemberConverterClass m1 = new MemberConverterClass {DefaultConverter = testDate, MemberConverter = testDate};
|
|
|
|
string json = JsonConvert.SerializeObject(m1, new JavaScriptDateTimeConverter());
|
|
Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
|
|
|
|
MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json, new JavaScriptDateTimeConverter());
|
|
|
|
Assert.AreEqual(testDate, m2.DefaultConverter);
|
|
Assert.AreEqual(testDate, m2.MemberConverter);
|
|
}
|
|
|
|
[Test]
|
|
public void ConverterAttributeExample()
|
|
{
|
|
DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
|
|
|
|
MemberConverterClass c = new MemberConverterClass
|
|
{
|
|
DefaultConverter = date,
|
|
MemberConverter = date
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Console.WriteLine(json);
|
|
//{
|
|
// "DefaultConverter": "\/Date(0)\/",
|
|
// "MemberConverter": "1970-01-01T00:00:00Z"
|
|
//}
|
|
}
|
|
|
|
[Test]
|
|
public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter()
|
|
{
|
|
ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass();
|
|
c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue");
|
|
c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue");
|
|
|
|
string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
|
|
Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json);
|
|
|
|
ClassAndMemberConverterClass c2 = JsonConvert.DeserializeObject<ClassAndMemberConverterClass>(json, new ArgumentConverterPrecedenceClassConverter());
|
|
|
|
Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue);
|
|
Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "JsonConverter IsoDateTimeConverter on Newtonsoft.Json.Tests.TestObjects.IncompatibleJsonAttributeClass is not compatible with member type IncompatibleJsonAttributeClass.")]
|
|
public void IncompatibleJsonAttributeShouldThrow()
|
|
{
|
|
IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass();
|
|
JsonConvert.SerializeObject(c);
|
|
}
|
|
|
|
[Test]
|
|
public void GenericAbstractProperty()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new GenericImpl());
|
|
Assert.AreEqual(@"{""Id"":0}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullable()
|
|
{
|
|
string json;
|
|
|
|
json = JsonConvert.SerializeObject((int?) null);
|
|
Assert.AreEqual("null", json);
|
|
|
|
json = JsonConvert.SerializeObject((int?) 1);
|
|
Assert.AreEqual("1", json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeJsonRaw()
|
|
{
|
|
PersonRaw personRaw = new PersonRaw
|
|
{
|
|
FirstName = "FirstNameValue",
|
|
RawContent = new JRaw("[1,2,3,4,5]"),
|
|
LastName = "LastNameValue"
|
|
};
|
|
|
|
string json;
|
|
|
|
json = JsonConvert.SerializeObject(personRaw);
|
|
Assert.AreEqual(@"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeJsonRaw()
|
|
{
|
|
string json = @"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}";
|
|
|
|
PersonRaw personRaw = JsonConvert.DeserializeObject<PersonRaw>(json);
|
|
|
|
Assert.AreEqual("FirstNameValue", personRaw.FirstName);
|
|
Assert.AreEqual("[1,2,3,4,5]", personRaw.RawContent.ToString());
|
|
Assert.AreEqual("LastNameValue", personRaw.LastName);
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void DeserializeNullableMember()
|
|
{
|
|
UserNullable userNullablle = new UserNullable
|
|
{
|
|
Id = new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"),
|
|
FName = "FirstValue",
|
|
LName = "LastValue",
|
|
RoleId = 5,
|
|
NullableRoleId = 6,
|
|
NullRoleId = null,
|
|
Active = true
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(userNullablle);
|
|
|
|
Assert.AreEqual(@"{""Id"":""ad6205e8-0df4-465d-aea6-8ba18e93a7e7"",""FName"":""FirstValue"",""LName"":""LastValue"",""RoleId"":5,""NullableRoleId"":6,""NullRoleId"":null,""Active"":true}", json);
|
|
|
|
UserNullable userNullablleDeserialized = JsonConvert.DeserializeObject<UserNullable>(json);
|
|
|
|
Assert.AreEqual(new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), userNullablleDeserialized.Id);
|
|
Assert.AreEqual("FirstValue", userNullablleDeserialized.FName);
|
|
Assert.AreEqual("LastValue", userNullablleDeserialized.LName);
|
|
Assert.AreEqual(5, userNullablleDeserialized.RoleId);
|
|
Assert.AreEqual(6, userNullablleDeserialized.NullableRoleId);
|
|
Assert.AreEqual(null, userNullablleDeserialized.NullRoleId);
|
|
Assert.AreEqual(true, userNullablleDeserialized.Active);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeInt64ToNullableDouble()
|
|
{
|
|
string json = @"{""Height"":1}";
|
|
|
|
DoubleClass c = JsonConvert.DeserializeObject<DoubleClass>(json);
|
|
Assert.AreEqual(1, c.Height);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeTypeProperty()
|
|
{
|
|
string boolRef = typeof (bool).AssemblyQualifiedName;
|
|
TypeClass typeClass = new TypeClass {TypeProperty = typeof (bool)};
|
|
|
|
string json = JsonConvert.SerializeObject(typeClass);
|
|
Assert.AreEqual(@"{""TypeProperty"":""" + boolRef + @"""}", json);
|
|
|
|
TypeClass typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
|
|
Assert.AreEqual(typeof (bool), typeClass2.TypeProperty);
|
|
|
|
string jsonSerializerTestRef = typeof (JsonSerializerTest).AssemblyQualifiedName;
|
|
typeClass = new TypeClass {TypeProperty = typeof (JsonSerializerTest)};
|
|
|
|
json = JsonConvert.SerializeObject(typeClass);
|
|
Assert.AreEqual(@"{""TypeProperty"":""" + jsonSerializerTestRef + @"""}", json);
|
|
|
|
typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
|
|
Assert.AreEqual(typeof (JsonSerializerTest), typeClass2.TypeProperty);
|
|
}
|
|
|
|
[Test]
|
|
public void RequiredMembersClass()
|
|
{
|
|
RequiredMembersClass c = new RequiredMembersClass()
|
|
{
|
|
BirthDate = new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc),
|
|
FirstName = "Bob",
|
|
LastName = "Smith",
|
|
MiddleName = "Cosmo"
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""FirstName"": ""Bob"",
|
|
""MiddleName"": ""Cosmo"",
|
|
""LastName"": ""Smith"",
|
|
""BirthDate"": ""\/Date(977309755000)\/""
|
|
}", json);
|
|
|
|
RequiredMembersClass c2 = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
|
|
|
|
Assert.AreEqual("Bob", c2.FirstName);
|
|
Assert.AreEqual(new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), c2.BirthDate);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeRequiredMembersClassWithNullValues()
|
|
{
|
|
string json = @"{
|
|
""FirstName"": ""I can't be null bro!"",
|
|
""MiddleName"": null,
|
|
""LastName"": null,
|
|
""BirthDate"": ""\/Date(977309755000)\/""
|
|
}";
|
|
|
|
RequiredMembersClass c = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
|
|
|
|
Assert.AreEqual("I can't be null bro!", c.FirstName);
|
|
Assert.AreEqual(null, c.MiddleName);
|
|
Assert.AreEqual(null, c.LastName);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Required property 'FirstName' expects a value but got null. Line 6, position 2.")]
|
|
public void DeserializeRequiredMembersClassNullRequiredValueProperty()
|
|
{
|
|
string json = @"{
|
|
""FirstName"": null,
|
|
""MiddleName"": null,
|
|
""LastName"": null,
|
|
""BirthDate"": ""\/Date(977309755000)\/""
|
|
}";
|
|
|
|
JsonConvert.DeserializeObject<RequiredMembersClass>(json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Cannot write a null value for property 'FirstName'. Property requires a value.")]
|
|
public void SerializeRequiredMembersClassNullRequiredValueProperty()
|
|
{
|
|
RequiredMembersClass requiredMembersClass = new RequiredMembersClass
|
|
{
|
|
FirstName = null,
|
|
BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc),
|
|
LastName = null,
|
|
MiddleName = null
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(requiredMembersClass);
|
|
Console.WriteLine(json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Required property 'LastName' not found in JSON. Line 3, position 2.")]
|
|
public void RequiredMembersClassMissingRequiredProperty()
|
|
{
|
|
string json = @"{
|
|
""FirstName"": ""Bob""
|
|
}";
|
|
|
|
JsonConvert.DeserializeObject<RequiredMembersClass>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeJaggedArray()
|
|
{
|
|
JaggedArray aa = new JaggedArray();
|
|
aa.Before = "Before!";
|
|
aa.After = "After!";
|
|
aa.Coordinates = new[] {new[] {1, 1}, new[] {1, 2}, new[] {2, 1}, new[] {2, 2}};
|
|
|
|
string json = JsonConvert.SerializeObject(aa);
|
|
|
|
Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeJaggedArray()
|
|
{
|
|
string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}";
|
|
|
|
JaggedArray aa = JsonConvert.DeserializeObject<JaggedArray>(json);
|
|
|
|
Assert.AreEqual("Before!", aa.Before);
|
|
Assert.AreEqual("After!", aa.After);
|
|
Assert.AreEqual(4, aa.Coordinates.Length);
|
|
Assert.AreEqual(2, aa.Coordinates[0].Length);
|
|
Assert.AreEqual(1, aa.Coordinates[0][0]);
|
|
Assert.AreEqual(2, aa.Coordinates[1][1]);
|
|
|
|
string after = JsonConvert.SerializeObject(aa);
|
|
|
|
Assert.AreEqual(json, after);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeGoogleGeoCode()
|
|
{
|
|
string json = @"{
|
|
""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"",
|
|
""Status"": {
|
|
""code"": 200,
|
|
""request"": ""geocode""
|
|
},
|
|
""Placemark"": [
|
|
{
|
|
""address"": ""1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"",
|
|
""AddressDetails"": {
|
|
""Country"": {
|
|
""CountryNameCode"": ""US"",
|
|
""AdministrativeArea"": {
|
|
""AdministrativeAreaName"": ""CA"",
|
|
""SubAdministrativeArea"": {
|
|
""SubAdministrativeAreaName"": ""Santa Clara"",
|
|
""Locality"": {
|
|
""LocalityName"": ""Mountain View"",
|
|
""Thoroughfare"": {
|
|
""ThoroughfareName"": ""1600 Amphitheatre Pkwy""
|
|
},
|
|
""PostalCode"": {
|
|
""PostalCodeNumber"": ""94043""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
""Accuracy"": 8
|
|
},
|
|
""Point"": {
|
|
""coordinates"": [-122.083739, 37.423021, 0]
|
|
}
|
|
}
|
|
]
|
|
}";
|
|
|
|
GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject<GoogleMapGeocoderStructure>(json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Could not create an instance of type Newtonsoft.Json.Tests.TestObjects.ICo. Type is an interface or abstract class and cannot be instantated. Line 1, position 14.")]
|
|
public void DeserializeInterfaceProperty()
|
|
{
|
|
InterfacePropertyTestClass testClass = new InterfacePropertyTestClass();
|
|
testClass.co = new Co();
|
|
String strFromTest = JsonConvert.SerializeObject(testClass);
|
|
InterfacePropertyTestClass testFromDe = (InterfacePropertyTestClass) JsonConvert.DeserializeObject(strFromTest, typeof (InterfacePropertyTestClass));
|
|
}
|
|
|
|
private Person GetPerson()
|
|
{
|
|
Person person = new Person
|
|
{
|
|
Name = "Mike Manager",
|
|
BirthDate = new DateTime(1983, 8, 3, 0, 0, 0, DateTimeKind.Utc),
|
|
Department = "IT",
|
|
LastModified = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)
|
|
};
|
|
return person;
|
|
}
|
|
|
|
//[Test]
|
|
public void WriteJsonToFile()
|
|
{
|
|
//Person person = GetPerson();
|
|
|
|
//string json = JsonConvert.SerializeObject(person, Formatting.Indented);
|
|
|
|
//File.WriteAllText(@"c:\person.json", json);
|
|
|
|
Person person = GetPerson();
|
|
|
|
using (FileStream fs = System.IO.File.Open(@"c:\person.json", FileMode.CreateNew))
|
|
using (StreamWriter sw = new StreamWriter(fs))
|
|
using (JsonWriter jw = new JsonTextWriter(sw))
|
|
{
|
|
jw.Formatting = Formatting.Indented;
|
|
|
|
JsonSerializer serializer = new JsonSerializer();
|
|
serializer.Serialize(jw, person);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void WriteJsonDates()
|
|
{
|
|
LogEntry entry = new LogEntry
|
|
{
|
|
LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
|
|
Details = "Application started."
|
|
};
|
|
|
|
string defaultJson = JsonConvert.SerializeObject(entry);
|
|
// {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
|
|
|
|
string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());
|
|
// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00.0000000Z"}
|
|
|
|
string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
|
|
// {"Details":"Application started.","LogDate":new Date(1234656000000)}
|
|
|
|
Console.WriteLine(defaultJson);
|
|
Console.WriteLine(isoJson);
|
|
Console.WriteLine(javascriptJson);
|
|
}
|
|
|
|
public void GenericListAndDictionaryInterfaceProperties()
|
|
{
|
|
GenericListAndDictionaryInterfaceProperties o = new GenericListAndDictionaryInterfaceProperties();
|
|
o.IDictionaryProperty = new Dictionary<string, int>
|
|
{
|
|
{"one", 1},
|
|
{"two", 2},
|
|
{"three", 3}
|
|
};
|
|
o.IListProperty = new List<int>
|
|
{
|
|
1, 2, 3
|
|
};
|
|
o.IEnumerableProperty = new List<int>
|
|
{
|
|
4, 5, 6
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(o, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""IEnumerableProperty"": [
|
|
4,
|
|
5,
|
|
6
|
|
],
|
|
""IListProperty"": [
|
|
1,
|
|
2,
|
|
3
|
|
],
|
|
""IDictionaryProperty"": {
|
|
""one"": 1,
|
|
""two"": 2,
|
|
""three"": 3
|
|
}
|
|
}", json);
|
|
|
|
GenericListAndDictionaryInterfaceProperties deserializedObject = JsonConvert.DeserializeObject<GenericListAndDictionaryInterfaceProperties>(json);
|
|
Assert.IsNotNull(deserializedObject);
|
|
|
|
CollectionAssert.AreEqual(o.IListProperty.ToArray(), deserializedObject.IListProperty.ToArray());
|
|
CollectionAssert.AreEqual(o.IEnumerableProperty.ToArray(), deserializedObject.IEnumerableProperty.ToArray());
|
|
CollectionAssert.AreEqual(o.IDictionaryProperty.ToArray(), deserializedObject.IDictionaryProperty.ToArray());
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeBestMatchPropertyCase()
|
|
{
|
|
string json = @"{
|
|
""firstName"": ""firstName"",
|
|
""FirstName"": ""FirstName"",
|
|
""LastName"": ""LastName"",
|
|
""lastName"": ""lastName"",
|
|
}";
|
|
|
|
PropertyCase o = JsonConvert.DeserializeObject<PropertyCase>(json);
|
|
Assert.IsNotNull(o);
|
|
|
|
Assert.AreEqual("firstName", o.firstName);
|
|
Assert.AreEqual("FirstName", o.FirstName);
|
|
Assert.AreEqual("LastName", o.LastName);
|
|
Assert.AreEqual("lastName", o.lastName);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializePropertiesOnToNonDefaultConstructor()
|
|
{
|
|
SubKlass i = new SubKlass("my subprop");
|
|
i.SuperProp = "overrided superprop";
|
|
|
|
string json = JsonConvert.SerializeObject(i);
|
|
Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json);
|
|
|
|
SubKlass ii = JsonConvert.DeserializeObject<SubKlass>(json);
|
|
|
|
string newJson = JsonConvert.SerializeObject(ii);
|
|
Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeJsonPropertyWithHandlingValues()
|
|
{
|
|
JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
|
|
o.DefaultValueHandlingIgnoreProperty = "Default!";
|
|
o.DefaultValueHandlingIncludeProperty = "Default!";
|
|
o.DefaultValueHandlingPopulateProperty = "Default!";
|
|
o.DefaultValueHandlingIgnoreAndPopulateProperty = "Default!";
|
|
|
|
string json = JsonConvert.SerializeObject(o, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""DefaultValueHandlingIncludeProperty"": ""Default!"",
|
|
""DefaultValueHandlingPopulateProperty"": ""Default!"",
|
|
""NullValueHandlingIncludeProperty"": null,
|
|
""ReferenceLoopHandlingErrorProperty"": null,
|
|
""ReferenceLoopHandlingIgnoreProperty"": null,
|
|
""ReferenceLoopHandlingSerializeProperty"": null
|
|
}", json);
|
|
|
|
json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});
|
|
|
|
Assert.AreEqual(@"{
|
|
""DefaultValueHandlingIncludeProperty"": ""Default!"",
|
|
""DefaultValueHandlingPopulateProperty"": ""Default!"",
|
|
""NullValueHandlingIncludeProperty"": null
|
|
}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeJsonPropertyWithHandlingValues()
|
|
{
|
|
string json = "{}";
|
|
|
|
JsonPropertyWithHandlingValues o = JsonConvert.DeserializeObject<JsonPropertyWithHandlingValues>(json);
|
|
Assert.AreEqual("Default!", o.DefaultValueHandlingIgnoreAndPopulateProperty);
|
|
Assert.AreEqual("Default!", o.DefaultValueHandlingPopulateProperty);
|
|
Assert.AreEqual(null, o.DefaultValueHandlingIgnoreProperty);
|
|
Assert.AreEqual(null, o.DefaultValueHandlingIncludeProperty);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException))]
|
|
public void JsonPropertyWithHandlingValues_ReferenceLoopError()
|
|
{
|
|
JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
|
|
o.ReferenceLoopHandlingErrorProperty = o;
|
|
|
|
JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore});
|
|
}
|
|
|
|
[Test]
|
|
public void PartialClassDeserialize()
|
|
{
|
|
string json = @"{
|
|
""request"": ""ux.settings.update"",
|
|
""sid"": ""14c561bd-32a8-457e-b4e5-4bba0832897f"",
|
|
""uid"": ""30c39065-0f31-de11-9442-001e3786a8ec"",
|
|
""fidOrder"": [
|
|
""id"",
|
|
""andytest_name"",
|
|
""andytest_age"",
|
|
""andytest_address"",
|
|
""andytest_phone"",
|
|
""date"",
|
|
""title"",
|
|
""titleId""
|
|
],
|
|
""entityName"": ""Andy Test"",
|
|
""setting"": ""entity.field.order""
|
|
}";
|
|
|
|
RequestOnly r = JsonConvert.DeserializeObject<RequestOnly>(json);
|
|
Assert.AreEqual("ux.settings.update", r.Request);
|
|
|
|
NonRequest n = JsonConvert.DeserializeObject<NonRequest>(json);
|
|
Assert.AreEqual(new Guid("14c561bd-32a8-457e-b4e5-4bba0832897f"), n.Sid);
|
|
Assert.AreEqual(new Guid("30c39065-0f31-de11-9442-001e3786a8ec"), n.Uid);
|
|
Assert.AreEqual(8, n.FidOrder.Count);
|
|
Assert.AreEqual("id", n.FidOrder[0]);
|
|
Assert.AreEqual("titleId", n.FidOrder[n.FidOrder.Count - 1]);
|
|
}
|
|
|
|
#if !SILVERLIGHT && !PocketPC && !NET20
|
|
[MetadataType(typeof (OptInClassMetadata))]
|
|
public class OptInClass
|
|
{
|
|
[DataContract]
|
|
public class OptInClassMetadata
|
|
{
|
|
[DataMember]
|
|
public string Name { get; set; }
|
|
|
|
[DataMember]
|
|
public int Age { get; set; }
|
|
|
|
public string NotIncluded { get; set; }
|
|
}
|
|
|
|
public string Name { get; set; }
|
|
public int Age { get; set; }
|
|
public string NotIncluded { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void OptInClassMetadataSerialization()
|
|
{
|
|
OptInClass optInClass = new OptInClass();
|
|
optInClass.Age = 26;
|
|
optInClass.Name = "James NK";
|
|
optInClass.NotIncluded = "Poor me :(";
|
|
|
|
string json = JsonConvert.SerializeObject(optInClass, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Name"": ""James NK"",
|
|
""Age"": 26
|
|
}", json);
|
|
|
|
OptInClass newOptInClass = JsonConvert.DeserializeObject<OptInClass>(@"{
|
|
""Name"": ""James NK"",
|
|
""NotIncluded"": ""Ignore me!"",
|
|
""Age"": 26
|
|
}");
|
|
Assert.AreEqual(26, newOptInClass.Age);
|
|
Assert.AreEqual("James NK", newOptInClass.Name);
|
|
Assert.AreEqual(null, newOptInClass.NotIncluded);
|
|
}
|
|
#endif
|
|
|
|
#if !PocketPC && !NET20
|
|
[DataContract]
|
|
public class DataContractPrivateMembers
|
|
{
|
|
public DataContractPrivateMembers()
|
|
{
|
|
}
|
|
|
|
public DataContractPrivateMembers(string name, int age, int rank, string title)
|
|
{
|
|
_name = name;
|
|
Age = age;
|
|
Rank = rank;
|
|
Title = title;
|
|
}
|
|
|
|
[DataMember] private string _name;
|
|
|
|
[DataMember(Name = "_age")]
|
|
private int Age { get; set; }
|
|
|
|
[JsonProperty]
|
|
private int Rank { get; set; }
|
|
|
|
[JsonProperty(PropertyName = "JsonTitle")]
|
|
[DataMember(Name = "DataTitle")]
|
|
private string Title { get; set; }
|
|
|
|
public string NotIncluded { get; set; }
|
|
|
|
public override string ToString()
|
|
{
|
|
return "_name: " + _name + ", _age: " + Age + ", Rank: " + Rank + ", JsonTitle: " + Title;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeDataContractPrivateMembers()
|
|
{
|
|
DataContractPrivateMembers c = new DataContractPrivateMembers("Jeff", 26, 10, "Dr");
|
|
c.NotIncluded = "Hi";
|
|
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""_name"": ""Jeff"",
|
|
""_age"": 26,
|
|
""Rank"": 10,
|
|
""JsonTitle"": ""Dr""
|
|
}", json);
|
|
|
|
DataContractPrivateMembers cc = JsonConvert.DeserializeObject<DataContractPrivateMembers>(json);
|
|
Assert.AreEqual("_name: Jeff, _age: 26, Rank: 10, JsonTitle: Dr", cc.ToString());
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void DeserializeDictionaryInterface()
|
|
{
|
|
string json = @"{
|
|
""Name"": ""Name!"",
|
|
""Dictionary"": {
|
|
""Item"": 11
|
|
}
|
|
}";
|
|
|
|
DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
|
|
new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace});
|
|
Assert.AreEqual("Name!", c.Name);
|
|
Assert.AreEqual(1, c.Dictionary.Count);
|
|
Assert.AreEqual(11, c.Dictionary["Item"]);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeDictionaryInterfaceWithExistingValues()
|
|
{
|
|
string json = @"{
|
|
""Random"": {
|
|
""blah"": 1
|
|
},
|
|
""Name"": ""Name!"",
|
|
""Dictionary"": {
|
|
""Item"": 11,
|
|
""Item1"": 12
|
|
},
|
|
""Collection"": [
|
|
999
|
|
],
|
|
""Employee"": {
|
|
""Manager"": {
|
|
""Name"": ""ManagerName!""
|
|
}
|
|
}
|
|
}";
|
|
|
|
DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
|
|
new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Reuse});
|
|
|
|
Assert.AreEqual("Name!", c.Name);
|
|
Assert.AreEqual(3, c.Dictionary.Count);
|
|
Assert.AreEqual(11, c.Dictionary["Item"]);
|
|
Assert.AreEqual(1, c.Dictionary["existing"]);
|
|
Assert.AreEqual(4, c.Collection.Count);
|
|
Assert.AreEqual(1, c.Collection.ElementAt(0));
|
|
Assert.AreEqual(999, c.Collection.ElementAt(3));
|
|
Assert.AreEqual("EmployeeName!", c.Employee.Name);
|
|
Assert.AreEqual("ManagerName!", c.Employee.Manager.Name);
|
|
Assert.IsNotNull(c.Random);
|
|
}
|
|
|
|
[Test]
|
|
public void TypedObjectDeserializationWithComments()
|
|
{
|
|
string json = @"/*comment*/ { /*comment*/
|
|
""Name"": /*comment*/ ""Apple"" /*comment*/, /*comment*/
|
|
""ExpiryDate"": ""\/Date(1230422400000)\/"",
|
|
""Price"": 3.99,
|
|
""Sizes"": /*comment*/ [ /*comment*/
|
|
""Small"", /*comment*/
|
|
""Medium"" /*comment*/,
|
|
/*comment*/ ""Large""
|
|
/*comment*/ ] /*comment*/
|
|
} /*comment*/";
|
|
|
|
Product deserializedProduct = (Product) JsonConvert.DeserializeObject(json, typeof (Product));
|
|
|
|
Assert.AreEqual("Apple", deserializedProduct.Name);
|
|
Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate);
|
|
Assert.AreEqual(3.99, deserializedProduct.Price);
|
|
Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
|
|
Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
|
|
Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
|
|
}
|
|
|
|
[Test]
|
|
public void NestedInsideOuterObject()
|
|
{
|
|
string json = @"{
|
|
""short"": {
|
|
""original"": ""http://www.contrast.ie/blog/online-marketing-2009/"",
|
|
""short"": ""m2sqc6"",
|
|
""shortened"": ""http://short.ie/m2sqc6"",
|
|
""error"": {
|
|
""code"": 0,
|
|
""msg"": ""No action taken""
|
|
}
|
|
}
|
|
}";
|
|
|
|
JObject o = JObject.Parse(json);
|
|
|
|
Shortie s = JsonConvert.DeserializeObject<Shortie>(o["short"].ToString());
|
|
Assert.IsNotNull(s);
|
|
|
|
Assert.AreEqual(s.Original, "http://www.contrast.ie/blog/online-marketing-2009/");
|
|
Assert.AreEqual(s.Short, "m2sqc6");
|
|
Assert.AreEqual(s.Shortened, "http://short.ie/m2sqc6");
|
|
}
|
|
|
|
[Test]
|
|
public void UriSerialization()
|
|
{
|
|
Uri uri = new Uri("http://codeplex.com");
|
|
string json = JsonConvert.SerializeObject(uri);
|
|
|
|
Assert.AreEqual("http://codeplex.com/", uri.ToString());
|
|
|
|
Uri newUri = JsonConvert.DeserializeObject<Uri>(json);
|
|
Assert.AreEqual(uri, newUri);
|
|
}
|
|
|
|
[Test]
|
|
public void AnonymousPlusLinqToSql()
|
|
{
|
|
var value = new
|
|
{
|
|
bar = new JObject(new JProperty("baz", 13))
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(value);
|
|
|
|
Assert.AreEqual(@"{""bar"":{""baz"":13}}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeEnumerableAsObject()
|
|
{
|
|
Content content = new Content
|
|
{
|
|
Text = "Blah, blah, blah",
|
|
Children = new List<Content>
|
|
{
|
|
new Content {Text = "First"},
|
|
new Content {Text = "Second"}
|
|
}
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(content, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Children"": [
|
|
{
|
|
""Children"": null,
|
|
""Text"": ""First""
|
|
},
|
|
{
|
|
""Children"": null,
|
|
""Text"": ""Second""
|
|
}
|
|
],
|
|
""Text"": ""Blah, blah, blah""
|
|
}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeEnumerableAsObject()
|
|
{
|
|
string json = @"{
|
|
""Children"": [
|
|
{
|
|
""Children"": null,
|
|
""Text"": ""First""
|
|
},
|
|
{
|
|
""Children"": null,
|
|
""Text"": ""Second""
|
|
}
|
|
],
|
|
""Text"": ""Blah, blah, blah""
|
|
}";
|
|
|
|
Content content = JsonConvert.DeserializeObject<Content>(json);
|
|
|
|
Assert.AreEqual("Blah, blah, blah", content.Text);
|
|
Assert.AreEqual(2, content.Children.Count);
|
|
Assert.AreEqual("First", content.Children[0].Text);
|
|
Assert.AreEqual("Second", content.Children[1].Text);
|
|
}
|
|
|
|
[Test]
|
|
public void RoleTransferTest()
|
|
{
|
|
string json = @"{""Operation"":""1"",""RoleName"":""Admin"",""Direction"":""0""}";
|
|
|
|
RoleTransfer r = JsonConvert.DeserializeObject<RoleTransfer>(json);
|
|
|
|
Assert.AreEqual(RoleTransferOperation.Second, r.Operation);
|
|
Assert.AreEqual("Admin", r.RoleName);
|
|
Assert.AreEqual(RoleTransferDirection.First, r.Direction);
|
|
}
|
|
|
|
[Test]
|
|
public void PrimitiveValuesInObjectArray()
|
|
{
|
|
string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}";
|
|
|
|
ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
|
|
|
|
Assert.AreEqual("Router", o.Action);
|
|
Assert.AreEqual("Navigate", o.Method);
|
|
Assert.AreEqual(2, o.Data.Length);
|
|
Assert.AreEqual("dashboard", o.Data[0]);
|
|
Assert.AreEqual(null, o.Data[1]);
|
|
}
|
|
|
|
[Test]
|
|
public void ComplexValuesInObjectArray()
|
|
{
|
|
string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}";
|
|
|
|
ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
|
|
|
|
Assert.AreEqual("Router", o.Action);
|
|
Assert.AreEqual("Navigate", o.Method);
|
|
Assert.AreEqual(3, o.Data.Length);
|
|
Assert.AreEqual("dashboard", o.Data[0]);
|
|
Assert.IsInstanceOfType(typeof (JArray), o.Data[1]);
|
|
Assert.AreEqual(4, ((JArray) o.Data[1]).Count);
|
|
Assert.IsInstanceOfType(typeof (JObject), o.Data[2]);
|
|
Assert.AreEqual(1, ((JObject) o.Data[2]).Count);
|
|
Assert.AreEqual(1, (int) ((JObject) o.Data[2])["one"]);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeGenericDictionary()
|
|
{
|
|
string json = @"{""key1"":""value1"",""key2"":""value2""}";
|
|
|
|
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
|
|
|
|
Console.WriteLine(values.Count);
|
|
// 2
|
|
|
|
Console.WriteLine(values["key1"]);
|
|
// value1
|
|
|
|
Assert.AreEqual(2, values.Count);
|
|
Assert.AreEqual("value1", values["key1"]);
|
|
Assert.AreEqual("value2", values["key2"]);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeGenericList()
|
|
{
|
|
Product p1 = new Product
|
|
{
|
|
Name = "Product 1",
|
|
Price = 99.95m,
|
|
ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc),
|
|
};
|
|
Product p2 = new Product
|
|
{
|
|
Name = "Product 2",
|
|
Price = 12.50m,
|
|
ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc),
|
|
};
|
|
|
|
List<Product> products = new List<Product>();
|
|
products.Add(p1);
|
|
products.Add(p2);
|
|
|
|
string json = JsonConvert.SerializeObject(products, Formatting.Indented);
|
|
//[
|
|
// {
|
|
// "Name": "Product 1",
|
|
// "ExpiryDate": "\/Date(978048000000)\/",
|
|
// "Price": 99.95,
|
|
// "Sizes": null
|
|
// },
|
|
// {
|
|
// "Name": "Product 2",
|
|
// "ExpiryDate": "\/Date(1248998400000)\/",
|
|
// "Price": 12.50,
|
|
// "Sizes": null
|
|
// }
|
|
//]
|
|
|
|
Assert.AreEqual(@"[
|
|
{
|
|
""Name"": ""Product 1"",
|
|
""ExpiryDate"": ""\/Date(978048000000)\/"",
|
|
""Price"": 99.95,
|
|
""Sizes"": null
|
|
},
|
|
{
|
|
""Name"": ""Product 2"",
|
|
""ExpiryDate"": ""\/Date(1248998400000)\/"",
|
|
""Price"": 12.50,
|
|
""Sizes"": null
|
|
}
|
|
]", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeGenericList()
|
|
{
|
|
string json = @"[
|
|
{
|
|
""Name"": ""Product 1"",
|
|
""ExpiryDate"": ""\/Date(978048000000)\/"",
|
|
""Price"": 99.95,
|
|
""Sizes"": null
|
|
},
|
|
{
|
|
""Name"": ""Product 2"",
|
|
""ExpiryDate"": ""\/Date(1248998400000)\/"",
|
|
""Price"": 12.50,
|
|
""Sizes"": null
|
|
}
|
|
]";
|
|
|
|
List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
|
|
|
|
Console.WriteLine(products.Count);
|
|
// 2
|
|
|
|
Product p1 = products[0];
|
|
|
|
Console.WriteLine(p1.Name);
|
|
// Product 1
|
|
|
|
Assert.AreEqual(2, products.Count);
|
|
Assert.AreEqual("Product 1", products[0].Name);
|
|
}
|
|
|
|
#if !PocketPC && !NET20
|
|
[Test]
|
|
public void DeserializeEmptyStringToNullableDateTime()
|
|
{
|
|
string json = @"{""DateTimeField"":""""}";
|
|
|
|
NullableDateTimeTestClass c = JsonConvert.DeserializeObject<NullableDateTimeTestClass>(json);
|
|
Assert.AreEqual(null, c.DateTimeField);
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.Event. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Line 1, position 15.")]
|
|
public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments()
|
|
{
|
|
string json = @"{""sublocation"":""AlertEmailSender.Program.Main"",""userId"":0,""type"":0,""summary"":""Loading settings variables"",""details"":null,""stackTrace"":"" at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n at System.Environment.get_StackTrace()\r\n at mr.Logging.Event..ctor(String summary) in C:\\Projects\\MRUtils\\Logging\\Event.vb:line 71\r\n at AlertEmailSender.Program.Main(String[] args) in C:\\Projects\\AlertEmailSender\\AlertEmailSender\\Program.cs:line 25"",""tag"":null,""time"":""\/Date(1249591032026-0400)\/""}";
|
|
|
|
Event e = JsonConvert.DeserializeObject<Event>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeObjectSetOnlyProperty()
|
|
{
|
|
string json = @"{'SetOnlyProperty':[1,2,3,4,5]}";
|
|
|
|
SetOnlyPropertyClass2 setOnly = JsonConvert.DeserializeObject<SetOnlyPropertyClass2>(json);
|
|
JArray a = (JArray) setOnly.GetValue();
|
|
Assert.AreEqual(5, a.Count);
|
|
Assert.AreEqual(1, (int) a[0]);
|
|
Assert.AreEqual(5, (int) a[a.Count - 1]);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeOptInClasses()
|
|
{
|
|
string json = @"{id: ""12"", name: ""test"", items: [{id: ""112"", name: ""testing""}]}";
|
|
|
|
ListTestClass l = JsonConvert.DeserializeObject<ListTestClass>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullableListWithNulls()
|
|
{
|
|
List<decimal?> l = JsonConvert.DeserializeObject<List<decimal?>>("[ 3.3, null, 1.1 ] ");
|
|
Assert.AreEqual(3, l.Count);
|
|
|
|
Assert.AreEqual(3.3m, l[0]);
|
|
Assert.AreEqual(null, l[1]);
|
|
Assert.AreEqual(1.1m, l[2]);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON array into type 'Newtonsoft.Json.Tests.TestObjects.Person'. Line 1, position 1.")]
|
|
public void CannotDeserializeArrayIntoObject()
|
|
{
|
|
string json = @"[]";
|
|
|
|
JsonConvert.DeserializeObject<Person>(json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'. Line 1, position 2.")]
|
|
public void CannotDeserializeObjectIntoArray()
|
|
{
|
|
string json = @"{}";
|
|
|
|
JsonConvert.DeserializeObject<List<Person>>(json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Cannot populate JSON array onto type 'Newtonsoft.Json.Tests.TestObjects.Person'. Line 1, position 1.")]
|
|
public void CannotPopulateArrayIntoObject()
|
|
{
|
|
string json = @"[]";
|
|
|
|
JsonConvert.PopulateObject(json, new Person());
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Cannot populate JSON object onto type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'. Line 1, position 2.")]
|
|
public void CannotPopulateObjectIntoArray()
|
|
{
|
|
string json = @"{}";
|
|
|
|
JsonConvert.PopulateObject(json, new List<Person>());
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeEmptyString()
|
|
{
|
|
string json = @"{""Name"":""""}";
|
|
|
|
Person p = JsonConvert.DeserializeObject<Person>(json);
|
|
Assert.AreEqual("", p.Name);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.")]
|
|
public void SerializePropertyGetError()
|
|
{
|
|
JsonConvert.SerializeObject(new MemoryStream());
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Error setting value to 'ReadTimeout' on 'System.IO.MemoryStream'.")]
|
|
public void DeserializePropertySetError()
|
|
{
|
|
JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:0}");
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonReaderException), ExpectedMessage = @"Could not convert string to integer: . Line 1, position 15.")]
|
|
public void DeserializeEnsureTypeEmptyStringToIntError()
|
|
{
|
|
JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:''}");
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Error converting value {null} to type 'System.Int32'. Line 1, position 17.")]
|
|
public void DeserializeEnsureTypeNullToIntError()
|
|
{
|
|
JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:null}");
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeGenericListOfStrings()
|
|
{
|
|
List<String> strings = new List<String>();
|
|
|
|
strings.Add("str_1");
|
|
strings.Add("str_2");
|
|
strings.Add("str_3");
|
|
|
|
string json = JsonConvert.SerializeObject(strings);
|
|
Assert.AreEqual(@"[""str_1"",""str_2"",""str_3""]", json);
|
|
}
|
|
|
|
[Test]
|
|
public void ConstructorReadonlyFieldsTest()
|
|
{
|
|
ConstructorReadonlyFields c1 = new ConstructorReadonlyFields("String!", int.MaxValue);
|
|
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""A"": ""String!"",
|
|
""B"": 2147483647
|
|
}", json);
|
|
|
|
ConstructorReadonlyFields c2 = JsonConvert.DeserializeObject<ConstructorReadonlyFields>(json);
|
|
Assert.AreEqual("String!", c2.A);
|
|
Assert.AreEqual(int.MaxValue, c2.B);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeStruct()
|
|
{
|
|
StructTest structTest = new StructTest
|
|
{
|
|
StringProperty = "StringProperty!",
|
|
StringField = "StringField",
|
|
IntProperty = 5,
|
|
IntField = 10
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(structTest, Formatting.Indented);
|
|
Console.WriteLine(json);
|
|
Assert.AreEqual(@"{
|
|
""StringField"": ""StringField"",
|
|
""IntField"": 10,
|
|
""StringProperty"": ""StringProperty!"",
|
|
""IntProperty"": 5
|
|
}", json);
|
|
|
|
StructTest deserialized = JsonConvert.DeserializeObject<StructTest>(json);
|
|
Assert.AreEqual(structTest.StringProperty, deserialized.StringProperty);
|
|
Assert.AreEqual(structTest.StringField, deserialized.StringField);
|
|
Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty);
|
|
Assert.AreEqual(structTest.IntField, deserialized.IntField);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeListWithJsonConverter()
|
|
{
|
|
Foo f = new Foo();
|
|
f.Bars.Add(new Bar {Id = 0});
|
|
f.Bars.Add(new Bar {Id = 1});
|
|
f.Bars.Add(new Bar {Id = 2});
|
|
|
|
string json = JsonConvert.SerializeObject(f, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""Bars"": [
|
|
0,
|
|
1,
|
|
2
|
|
]
|
|
}", json);
|
|
|
|
Foo newFoo = JsonConvert.DeserializeObject<Foo>(json);
|
|
Assert.AreEqual(3, newFoo.Bars.Count);
|
|
Assert.AreEqual(0, newFoo.Bars[0].Id);
|
|
Assert.AreEqual(1, newFoo.Bars[1].Id);
|
|
Assert.AreEqual(2, newFoo.Bars[2].Id);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeGuidKeyedDictionary()
|
|
{
|
|
Dictionary<Guid, int> dictionary = new Dictionary<Guid, int>();
|
|
dictionary.Add(new Guid("F60EAEE0-AE47-488E-B330-59527B742D77"), 1);
|
|
dictionary.Add(new Guid("C2594C02-EBA1-426A-AA87-8DD8871350B0"), 2);
|
|
|
|
string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""f60eaee0-ae47-488e-b330-59527b742d77"": 1,
|
|
""c2594c02-eba1-426a-aa87-8dd8871350b0"": 2
|
|
}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializePersonKeyedDictionary()
|
|
{
|
|
Dictionary<Person, int> dictionary = new Dictionary<Person, int>();
|
|
dictionary.Add(new Person {Name = "p1"}, 1);
|
|
dictionary.Add(new Person {Name = "p2"}, 2);
|
|
|
|
string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
|
|
""Newtonsoft.Json.Tests.TestObjects.Person"": 2
|
|
}", json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Could not convert string 'Newtonsoft.Json.Tests.TestObjects.Person' to dictionary key type 'Newtonsoft.Json.Tests.TestObjects.Person'. Create a TypeConverter to convert from the string to the key type object. Line 2, position 46.")]
|
|
public void DeserializePersonKeyedDictionary()
|
|
{
|
|
string json =
|
|
@"{
|
|
""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
|
|
""Newtonsoft.Json.Tests.TestObjects.Person"": 2
|
|
}";
|
|
|
|
JsonConvert.DeserializeObject<Dictionary<Person, int>>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeFragment()
|
|
{
|
|
string googleSearchText = @"{
|
|
""responseData"": {
|
|
""results"": [
|
|
{
|
|
""GsearchResultClass"": ""GwebSearch"",
|
|
""unescapedUrl"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
|
|
""url"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
|
|
""visibleUrl"": ""en.wikipedia.org"",
|
|
""cacheUrl"": ""http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org"",
|
|
""title"": ""<b>Paris Hilton</b> - Wikipedia, the free encyclopedia"",
|
|
""titleNoFormatting"": ""Paris Hilton - Wikipedia, the free encyclopedia"",
|
|
""content"": ""[1] In 2006, she released her debut album...""
|
|
},
|
|
{
|
|
""GsearchResultClass"": ""GwebSearch"",
|
|
""unescapedUrl"": ""http://www.imdb.com/name/nm0385296/"",
|
|
""url"": ""http://www.imdb.com/name/nm0385296/"",
|
|
""visibleUrl"": ""www.imdb.com"",
|
|
""cacheUrl"": ""http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com"",
|
|
""title"": ""<b>Paris Hilton</b>"",
|
|
""titleNoFormatting"": ""Paris Hilton"",
|
|
""content"": ""Self: Zoolander. Socialite <b>Paris Hilton</b>...""
|
|
}
|
|
],
|
|
""cursor"": {
|
|
""pages"": [
|
|
{
|
|
""start"": ""0"",
|
|
""label"": 1
|
|
},
|
|
{
|
|
""start"": ""4"",
|
|
""label"": 2
|
|
},
|
|
{
|
|
""start"": ""8"",
|
|
""label"": 3
|
|
},
|
|
{
|
|
""start"": ""12"",
|
|
""label"": 4
|
|
}
|
|
],
|
|
""estimatedResultCount"": ""59600000"",
|
|
""currentPageIndex"": 0,
|
|
""moreResultsUrl"": ""http://www.google.com/search?oe=utf8&ie=utf8...""
|
|
}
|
|
},
|
|
""responseDetails"": null,
|
|
""responseStatus"": 200
|
|
}";
|
|
|
|
JObject googleSearch = JObject.Parse(googleSearchText);
|
|
|
|
// get JSON result objects into a list
|
|
IList<JToken> results = googleSearch["responseData"]["results"].Children().ToList();
|
|
|
|
// serialize JSON results into .NET objects
|
|
IList<SearchResult> searchResults = new List<SearchResult>();
|
|
foreach (JToken result in results)
|
|
{
|
|
SearchResult searchResult = JsonConvert.DeserializeObject<SearchResult>(result.ToString());
|
|
searchResults.Add(searchResult);
|
|
}
|
|
|
|
// Title = <b>Paris Hilton</b> - Wikipedia, the free encyclopedia
|
|
// Content = [1] In 2006, she released her debut album...
|
|
// Url = http://en.wikipedia.org/wiki/Paris_Hilton
|
|
|
|
// Title = <b>Paris Hilton</b>
|
|
// Content = Self: Zoolander. Socialite <b>Paris Hilton</b>...
|
|
// Url = http://www.imdb.com/name/nm0385296/
|
|
|
|
Assert.AreEqual(2, searchResults.Count);
|
|
Assert.AreEqual("<b>Paris Hilton</b> - Wikipedia, the free encyclopedia", searchResults[0].Title);
|
|
Assert.AreEqual("<b>Paris Hilton</b>", searchResults[1].Title);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeBaseReferenceWithDerivedValue()
|
|
{
|
|
PersonPropertyClass personPropertyClass = new PersonPropertyClass();
|
|
WagePerson wagePerson = (WagePerson) personPropertyClass.Person;
|
|
|
|
wagePerson.BirthDate = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
|
|
wagePerson.Department = "McDees";
|
|
wagePerson.HourlyWage = 12.50m;
|
|
wagePerson.LastModified = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
|
|
wagePerson.Name = "Jim Bob";
|
|
|
|
string json = JsonConvert.SerializeObject(personPropertyClass, Formatting.Indented);
|
|
Assert.AreEqual(
|
|
@"{
|
|
""Person"": {
|
|
""HourlyWage"": 12.50,
|
|
""Name"": ""Jim Bob"",
|
|
""BirthDate"": ""\/Date(975542399000)\/"",
|
|
""LastModified"": ""\/Date(975542399000)\/""
|
|
}
|
|
}",
|
|
json);
|
|
|
|
PersonPropertyClass newPersonPropertyClass = JsonConvert.DeserializeObject<PersonPropertyClass>(json);
|
|
Assert.AreEqual(wagePerson.HourlyWage, ((WagePerson) newPersonPropertyClass.Person).HourlyWage);
|
|
}
|
|
|
|
public class ExistingValueClass
|
|
{
|
|
public Dictionary<string, string> Dictionary { get; set; }
|
|
public List<string> List { get; set; }
|
|
|
|
public ExistingValueClass()
|
|
{
|
|
Dictionary = new Dictionary<string, string>
|
|
{
|
|
{"existing", "yup"}
|
|
};
|
|
List = new List<string>
|
|
{
|
|
"existing"
|
|
};
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializePopulateDictionaryAndList()
|
|
{
|
|
ExistingValueClass d = JsonConvert.DeserializeObject<ExistingValueClass>(@"{'Dictionary':{appended:'appended',existing:'new'}}");
|
|
|
|
Assert.IsNotNull(d);
|
|
Assert.IsNotNull(d.Dictionary);
|
|
Assert.AreEqual(typeof (Dictionary<string, string>), d.Dictionary.GetType());
|
|
Assert.AreEqual(typeof (List<string>), d.List.GetType());
|
|
Assert.AreEqual(2, d.Dictionary.Count);
|
|
Assert.AreEqual("new", d.Dictionary["existing"]);
|
|
Assert.AreEqual("appended", d.Dictionary["appended"]);
|
|
Assert.AreEqual(1, d.List.Count);
|
|
Assert.AreEqual("existing", d.List[0]);
|
|
}
|
|
|
|
public interface IKeyValueId
|
|
{
|
|
int Id { get; set; }
|
|
string Key { get; set; }
|
|
string Value { get; set; }
|
|
}
|
|
|
|
|
|
public class KeyValueId : IKeyValueId
|
|
{
|
|
public int Id { get; set; }
|
|
public string Key { get; set; }
|
|
public string Value { get; set; }
|
|
}
|
|
|
|
public class ThisGenericTest<T> where T : IKeyValueId
|
|
{
|
|
private Dictionary<string, T> _dict1 = new Dictionary<string, T>();
|
|
|
|
public string MyProperty { get; set; }
|
|
|
|
public void Add(T item)
|
|
{
|
|
this._dict1.Add(item.Key, item);
|
|
}
|
|
|
|
public T this[string key]
|
|
{
|
|
get { return this._dict1[key]; }
|
|
set { this._dict1[key] = value; }
|
|
}
|
|
|
|
public T this[int id]
|
|
{
|
|
get { return this._dict1.Values.FirstOrDefault(x => x.Id == id); }
|
|
set
|
|
{
|
|
var item = this[id];
|
|
|
|
if (item == null)
|
|
this.Add(value);
|
|
else
|
|
this._dict1[item.Key] = value;
|
|
}
|
|
}
|
|
|
|
public string ToJson()
|
|
{
|
|
return JsonConvert.SerializeObject(this, Formatting.Indented);
|
|
}
|
|
|
|
public T[] TheItems
|
|
{
|
|
get { return this._dict1.Values.ToArray<T>(); }
|
|
set
|
|
{
|
|
foreach (var item in value)
|
|
this.Add(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void IgnoreIndexedProperties()
|
|
{
|
|
ThisGenericTest<KeyValueId> g = new ThisGenericTest<KeyValueId>();
|
|
|
|
g.Add(new KeyValueId {Id = 1, Key = "key1", Value = "value1"});
|
|
g.Add(new KeyValueId {Id = 2, Key = "key2", Value = "value2"});
|
|
|
|
g.MyProperty = "some value";
|
|
|
|
string json = g.ToJson();
|
|
|
|
Assert.AreEqual(@"{
|
|
""MyProperty"": ""some value"",
|
|
""TheItems"": [
|
|
{
|
|
""Id"": 1,
|
|
""Key"": ""key1"",
|
|
""Value"": ""value1""
|
|
},
|
|
{
|
|
""Id"": 2,
|
|
""Key"": ""key2"",
|
|
""Value"": ""value2""
|
|
}
|
|
]
|
|
}", json);
|
|
|
|
ThisGenericTest<KeyValueId> gen = JsonConvert.DeserializeObject<ThisGenericTest<KeyValueId>>(json);
|
|
Assert.AreEqual("some value", gen.MyProperty);
|
|
}
|
|
|
|
public class JRawValueTestObject
|
|
{
|
|
public JRaw Value { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void JRawValue()
|
|
{
|
|
JRawValueTestObject deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:3}");
|
|
Assert.AreEqual("3", deserialized.Value.ToString());
|
|
|
|
deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:'3'}");
|
|
Assert.AreEqual(@"""3""", deserialized.Value.ToString());
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Unable to find a default constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+DictionaryWithNoDefaultConstructor. Line 1, position 6.")]
|
|
public void DeserializeDictionaryWithNoDefaultConstructor()
|
|
{
|
|
string json = "{key1:'value',key2:'value',key3:'value'}";
|
|
JsonConvert.DeserializeObject<DictionaryWithNoDefaultConstructor>(json);
|
|
}
|
|
|
|
public class DictionaryWithNoDefaultConstructor : Dictionary<string, string>
|
|
{
|
|
public DictionaryWithNoDefaultConstructor(IEnumerable<KeyValuePair<string, string>> initial)
|
|
{
|
|
foreach (KeyValuePair<string, string> pair in initial)
|
|
{
|
|
Add(pair.Key, pair.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class A
|
|
{
|
|
[JsonProperty("A1")] private string _A1;
|
|
|
|
public string A1
|
|
{
|
|
get { return _A1; }
|
|
set { _A1 = value; }
|
|
}
|
|
|
|
[JsonProperty("A2")]
|
|
private string A2 { get; set; }
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class B : A
|
|
{
|
|
public string B1 { get; set; }
|
|
|
|
[JsonProperty("B2")] private string _B2;
|
|
|
|
public string B2
|
|
{
|
|
get { return _B2; }
|
|
set { _B2 = value; }
|
|
}
|
|
|
|
[JsonProperty("B3")]
|
|
private string B3 { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeNonPublicBaseJsonProperties()
|
|
{
|
|
B value = new B();
|
|
string json = JsonConvert.SerializeObject(value, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""B2"": null,
|
|
""A1"": null,
|
|
""B3"": null,
|
|
""A2"": null
|
|
}", json);
|
|
}
|
|
|
|
public class TestClass
|
|
{
|
|
public string Key { get; set; }
|
|
public object Value { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeToObjectProperty()
|
|
{
|
|
var json = "{ Key: 'abc', Value: 123 }";
|
|
var item = JsonConvert.DeserializeObject<TestClass>(json);
|
|
|
|
Assert.AreEqual(123, item.Value);
|
|
}
|
|
|
|
public abstract class Animal
|
|
{
|
|
public abstract string Name { get; }
|
|
}
|
|
|
|
public class Human : Animal
|
|
{
|
|
public override string Name
|
|
{
|
|
get { return typeof (Human).Name; }
|
|
}
|
|
|
|
public string Ethnicity { get; set; }
|
|
}
|
|
|
|
#if !NET20 && !PocketPC && !WINDOWS_PHONE
|
|
public class DataContractJsonSerializerTestClass
|
|
{
|
|
public TimeSpan TimeSpanProperty { get; set; }
|
|
public Guid GuidProperty { get; set; }
|
|
public Animal AnimalProperty { get; set; }
|
|
public Exception ExceptionProperty { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void DataContractJsonSerializerTest()
|
|
{
|
|
Exception ex = new Exception("Blah blah blah");
|
|
|
|
DataContractJsonSerializerTestClass c = new DataContractJsonSerializerTestClass();
|
|
c.TimeSpanProperty = new TimeSpan(200, 20, 59, 30, 900);
|
|
c.GuidProperty = new Guid("66143115-BE2A-4a59-AF0A-348E1EA15B1E");
|
|
c.AnimalProperty = new Human() {Ethnicity = "European"};
|
|
c.ExceptionProperty = ex;
|
|
|
|
MemoryStream ms = new MemoryStream();
|
|
DataContractJsonSerializer serializer = new DataContractJsonSerializer(
|
|
typeof (DataContractJsonSerializerTestClass),
|
|
new Type[] {typeof (Human)});
|
|
serializer.WriteObject(ms, c);
|
|
|
|
byte[] jsonBytes = ms.ToArray();
|
|
string json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length);
|
|
|
|
Console.WriteLine(JObject.Parse(json).ToString());
|
|
Console.WriteLine();
|
|
|
|
Console.WriteLine(JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings
|
|
{
|
|
// TypeNameHandling = TypeNameHandling.Objects
|
|
}));
|
|
}
|
|
#endif
|
|
|
|
public class ModelStateDictionary<T> : IDictionary<string, T>
|
|
{
|
|
|
|
private readonly Dictionary<string, T> _innerDictionary = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
public ModelStateDictionary()
|
|
{
|
|
}
|
|
|
|
public ModelStateDictionary(ModelStateDictionary<T> dictionary)
|
|
{
|
|
if (dictionary == null)
|
|
{
|
|
throw new ArgumentNullException("dictionary");
|
|
}
|
|
|
|
foreach (var entry in dictionary)
|
|
{
|
|
_innerDictionary.Add(entry.Key, entry.Value);
|
|
}
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get { return _innerDictionary.Count; }
|
|
}
|
|
|
|
public bool IsReadOnly
|
|
{
|
|
get { return ((IDictionary<string, T>) _innerDictionary).IsReadOnly; }
|
|
}
|
|
|
|
public ICollection<string> Keys
|
|
{
|
|
get { return _innerDictionary.Keys; }
|
|
}
|
|
|
|
public T this[string key]
|
|
{
|
|
get
|
|
{
|
|
T value;
|
|
_innerDictionary.TryGetValue(key, out value);
|
|
return value;
|
|
}
|
|
set { _innerDictionary[key] = value; }
|
|
}
|
|
|
|
public ICollection<T> Values
|
|
{
|
|
get { return _innerDictionary.Values; }
|
|
}
|
|
|
|
public void Add(KeyValuePair<string, T> item)
|
|
{
|
|
((IDictionary<string, T>) _innerDictionary).Add(item);
|
|
}
|
|
|
|
public void Add(string key, T value)
|
|
{
|
|
_innerDictionary.Add(key, value);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_innerDictionary.Clear();
|
|
}
|
|
|
|
public bool Contains(KeyValuePair<string, T> item)
|
|
{
|
|
return ((IDictionary<string, T>) _innerDictionary).Contains(item);
|
|
}
|
|
|
|
public bool ContainsKey(string key)
|
|
{
|
|
return _innerDictionary.ContainsKey(key);
|
|
}
|
|
|
|
public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
|
|
{
|
|
((IDictionary<string, T>) _innerDictionary).CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
|
|
{
|
|
return _innerDictionary.GetEnumerator();
|
|
}
|
|
|
|
public void Merge(ModelStateDictionary<T> dictionary)
|
|
{
|
|
if (dictionary == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (var entry in dictionary)
|
|
{
|
|
this[entry.Key] = entry.Value;
|
|
}
|
|
}
|
|
|
|
public bool Remove(KeyValuePair<string, T> item)
|
|
{
|
|
return ((IDictionary<string, T>) _innerDictionary).Remove(item);
|
|
}
|
|
|
|
public bool Remove(string key)
|
|
{
|
|
return _innerDictionary.Remove(key);
|
|
}
|
|
|
|
public bool TryGetValue(string key, out T value)
|
|
{
|
|
return _innerDictionary.TryGetValue(key, out value);
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return ((IEnumerable) _innerDictionary).GetEnumerator();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeNonIDictionary()
|
|
{
|
|
ModelStateDictionary<string> modelStateDictionary = new ModelStateDictionary<string>();
|
|
modelStateDictionary.Add("key", "value");
|
|
|
|
string json = JsonConvert.SerializeObject(modelStateDictionary);
|
|
|
|
Assert.AreEqual(@"{""key"":""value""}", json);
|
|
|
|
ModelStateDictionary<string> newModelStateDictionary = JsonConvert.DeserializeObject<ModelStateDictionary<string>>(json);
|
|
Assert.AreEqual(1, newModelStateDictionary.Count);
|
|
Assert.AreEqual("value", newModelStateDictionary["key"]);
|
|
}
|
|
|
|
#if !SILVERLIGHT && !PocketPC
|
|
public class ISerializableTestObject : ISerializable
|
|
{
|
|
internal string _stringValue;
|
|
internal int _intValue;
|
|
internal DateTimeOffset _dateTimeOffsetValue;
|
|
internal Person _personValue;
|
|
internal Person _nullPersonValue;
|
|
internal int? _nullableInt;
|
|
internal bool _booleanValue;
|
|
internal byte _byteValue;
|
|
internal char _charValue;
|
|
internal DateTime _dateTimeValue;
|
|
internal decimal _decimalValue;
|
|
internal short _shortValue;
|
|
internal long _longValue;
|
|
internal sbyte _sbyteValue;
|
|
internal float _floatValue;
|
|
internal ushort _ushortValue;
|
|
internal uint _uintValue;
|
|
internal ulong _ulongValue;
|
|
|
|
public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue)
|
|
{
|
|
_stringValue = stringValue;
|
|
_intValue = intValue;
|
|
_dateTimeOffsetValue = dateTimeOffset;
|
|
_personValue = personValue;
|
|
_dateTimeValue = new DateTime(0, DateTimeKind.Utc);
|
|
}
|
|
|
|
protected ISerializableTestObject(SerializationInfo info, StreamingContext context)
|
|
{
|
|
_stringValue = info.GetString("stringValue");
|
|
_intValue = info.GetInt32("intValue");
|
|
_dateTimeOffsetValue = (DateTimeOffset) info.GetValue("dateTimeOffsetValue", typeof (DateTimeOffset));
|
|
_personValue = (Person) info.GetValue("personValue", typeof (Person));
|
|
_nullPersonValue = (Person) info.GetValue("nullPersonValue", typeof (Person));
|
|
_nullableInt = (int?) info.GetValue("nullableInt", typeof (int?));
|
|
|
|
_booleanValue = info.GetBoolean("booleanValue");
|
|
_byteValue = info.GetByte("byteValue");
|
|
_charValue = info.GetChar("charValue");
|
|
_dateTimeValue = info.GetDateTime("dateTimeValue");
|
|
_decimalValue = info.GetDecimal("decimalValue");
|
|
_shortValue = info.GetInt16("shortValue");
|
|
_longValue = info.GetInt64("longValue");
|
|
_sbyteValue = info.GetSByte("sbyteValue");
|
|
_floatValue = info.GetSingle("floatValue");
|
|
_ushortValue = info.GetUInt16("ushortValue");
|
|
_uintValue = info.GetUInt32("uintValue");
|
|
_ulongValue = info.GetUInt64("ulongValue");
|
|
}
|
|
|
|
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
|
{
|
|
info.AddValue("stringValue", _stringValue);
|
|
info.AddValue("intValue", _intValue);
|
|
info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue);
|
|
info.AddValue("personValue", _personValue);
|
|
info.AddValue("nullPersonValue", _nullPersonValue);
|
|
info.AddValue("nullableInt", null);
|
|
|
|
info.AddValue("booleanValue", _booleanValue);
|
|
info.AddValue("byteValue", _byteValue);
|
|
info.AddValue("charValue", _charValue);
|
|
info.AddValue("dateTimeValue", _dateTimeValue);
|
|
info.AddValue("decimalValue", _decimalValue);
|
|
info.AddValue("shortValue", _shortValue);
|
|
info.AddValue("longValue", _longValue);
|
|
info.AddValue("sbyteValue", _sbyteValue);
|
|
info.AddValue("floatValue", _floatValue);
|
|
info.AddValue("ushortValue", _ushortValue);
|
|
info.AddValue("uintValue", _uintValue);
|
|
info.AddValue("ulongValue", _ulongValue);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeISerializableTestObject()
|
|
{
|
|
Person person = new Person();
|
|
person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
|
|
person.LastModified = person.BirthDate;
|
|
person.Department = "Department!";
|
|
person.Name = "Name!";
|
|
|
|
DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2));
|
|
string dateTimeOffsetText;
|
|
#if !NET20
|
|
dateTimeOffsetText = @"\/Date(977345999000+0200)\/";
|
|
#else
|
|
dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00";
|
|
#endif
|
|
|
|
ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person);
|
|
|
|
string json = JsonConvert.SerializeObject(o, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""stringValue"": ""String!"",
|
|
""intValue"": -2147483648,
|
|
""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""",
|
|
""personValue"": {
|
|
""Name"": ""Name!"",
|
|
""BirthDate"": ""\/Date(946688461000)\/"",
|
|
""LastModified"": ""\/Date(946688461000)\/""
|
|
},
|
|
""nullPersonValue"": null,
|
|
""nullableInt"": null,
|
|
""booleanValue"": false,
|
|
""byteValue"": 0,
|
|
""charValue"": ""\u0000"",
|
|
""dateTimeValue"": ""\/Date(-62135596800000)\/"",
|
|
""decimalValue"": 0.0,
|
|
""shortValue"": 0,
|
|
""longValue"": 0,
|
|
""sbyteValue"": 0,
|
|
""floatValue"": 0.0,
|
|
""ushortValue"": 0,
|
|
""uintValue"": 0,
|
|
""ulongValue"": 0
|
|
}", json);
|
|
|
|
ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
|
|
Assert.AreEqual("String!", o2._stringValue);
|
|
Assert.AreEqual(int.MinValue, o2._intValue);
|
|
Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
|
|
Assert.AreEqual("Name!", o2._personValue.Name);
|
|
Assert.AreEqual(null, o2._nullPersonValue);
|
|
Assert.AreEqual(null, o2._nullableInt);
|
|
}
|
|
#endif
|
|
|
|
public class KVPair<TKey, TValue>
|
|
{
|
|
public TKey Key { get; set; }
|
|
public TValue Value { get; set; }
|
|
|
|
public KVPair(TKey k, TValue v)
|
|
{
|
|
Key = k;
|
|
Value = v;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeUsingNonDefaultConstructorWithLeftOverValues()
|
|
{
|
|
List<KVPair<string, string>> kvPairs =
|
|
JsonConvert.DeserializeObject<List<KVPair<string, string>>>(
|
|
"[{\"Key\":\"Two\",\"Value\":\"2\"},{\"Key\":\"One\",\"Value\":\"1\"}]");
|
|
|
|
Assert.AreEqual(2, kvPairs.Count);
|
|
Assert.AreEqual("Two", kvPairs[0].Key);
|
|
Assert.AreEqual("2", kvPairs[0].Value);
|
|
Assert.AreEqual("One", kvPairs[1].Key);
|
|
Assert.AreEqual("1", kvPairs[1].Value);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeClassWithInheritedProtectedMember()
|
|
{
|
|
AA myA = new AA(2);
|
|
string json = JsonConvert.SerializeObject(myA, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""AA_field1"": 2,
|
|
""AA_property1"": 2,
|
|
""AA_property2"": 2,
|
|
""AA_property3"": 2,
|
|
""AA_property4"": 2
|
|
}", json);
|
|
|
|
BB myB = new BB(3, 4);
|
|
json = JsonConvert.SerializeObject(myB, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""BB_field1"": 4,
|
|
""BB_field2"": 4,
|
|
""AA_field1"": 3,
|
|
""BB_property1"": 4,
|
|
""BB_property2"": 4,
|
|
""BB_property3"": 4,
|
|
""BB_property4"": 4,
|
|
""BB_property5"": 4,
|
|
""BB_property7"": 4,
|
|
""AA_property1"": 3,
|
|
""AA_property2"": 3,
|
|
""AA_property3"": 3,
|
|
""AA_property4"": 3
|
|
}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeClassWithInheritedProtectedMember()
|
|
{
|
|
AA myA = JsonConvert.DeserializeObject<AA>(
|
|
@"{
|
|
""AA_field1"": 2,
|
|
""AA_field2"": 2,
|
|
""AA_property1"": 2,
|
|
""AA_property2"": 2,
|
|
""AA_property3"": 2,
|
|
""AA_property4"": 2,
|
|
""AA_property5"": 2,
|
|
""AA_property6"": 2
|
|
}");
|
|
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof (AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myA));
|
|
|
|
BB myB = JsonConvert.DeserializeObject<BB>(
|
|
@"{
|
|
""BB_field1"": 4,
|
|
""BB_field2"": 4,
|
|
""AA_field1"": 3,
|
|
""AA_field2"": 3,
|
|
""AA_property1"": 2,
|
|
""AA_property2"": 2,
|
|
""AA_property3"": 2,
|
|
""AA_property4"": 2,
|
|
""AA_property5"": 2,
|
|
""AA_property6"": 2,
|
|
""BB_property1"": 3,
|
|
""BB_property2"": 3,
|
|
""BB_property3"": 3,
|
|
""BB_property4"": 3,
|
|
""BB_property5"": 3,
|
|
""BB_property6"": 3,
|
|
""BB_property7"": 3,
|
|
""BB_property8"": 3
|
|
}");
|
|
|
|
Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof (AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof (AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof (AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
|
|
Assert.AreEqual(4, myB.BB_field1);
|
|
Assert.AreEqual(4, myB.BB_field2);
|
|
Assert.AreEqual(3, myB.BB_property1);
|
|
Assert.AreEqual(3, myB.BB_property2);
|
|
Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof (BB).GetProperty("BB_property3", BindingFlags.Instance | BindingFlags.Public), myB));
|
|
Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof (BB).GetProperty("BB_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
|
|
Assert.AreEqual(0, myB.BB_property5);
|
|
Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof (BB).GetProperty("BB_property6", BindingFlags.Instance | BindingFlags.Public), myB));
|
|
Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof (BB).GetProperty("BB_property7", BindingFlags.Instance | BindingFlags.Public), myB));
|
|
Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof (BB).GetProperty("BB_property8", BindingFlags.Instance | BindingFlags.Public), myB));
|
|
}
|
|
|
|
public class AA
|
|
{
|
|
[JsonProperty] protected int AA_field1;
|
|
protected int AA_field2;
|
|
|
|
[JsonProperty]
|
|
protected int AA_property1 { get; set; }
|
|
|
|
[JsonProperty]
|
|
protected int AA_property2 { get; private set; }
|
|
|
|
[JsonProperty]
|
|
protected int AA_property3 { private get; set; }
|
|
|
|
[JsonProperty]
|
|
private int AA_property4 { get; set; }
|
|
|
|
protected int AA_property5 { get; private set; }
|
|
protected int AA_property6 { private get; set; }
|
|
|
|
public AA()
|
|
{
|
|
}
|
|
|
|
public AA(int f)
|
|
{
|
|
AA_field1 = f;
|
|
AA_field2 = f;
|
|
AA_property1 = f;
|
|
AA_property2 = f;
|
|
AA_property3 = f;
|
|
AA_property4 = f;
|
|
AA_property5 = f;
|
|
AA_property6 = f;
|
|
}
|
|
}
|
|
|
|
public class BB : AA
|
|
{
|
|
[JsonProperty] public int BB_field1;
|
|
public int BB_field2;
|
|
|
|
[JsonProperty]
|
|
public int BB_property1 { get; set; }
|
|
|
|
[JsonProperty]
|
|
public int BB_property2 { get; private set; }
|
|
|
|
[JsonProperty]
|
|
public int BB_property3 { private get; set; }
|
|
|
|
[JsonProperty]
|
|
private int BB_property4 { get; set; }
|
|
|
|
public int BB_property5 { get; private set; }
|
|
public int BB_property6 { private get; set; }
|
|
|
|
[JsonProperty]
|
|
public int BB_property7 { protected get; set; }
|
|
|
|
public int BB_property8 { protected get; set; }
|
|
|
|
public BB()
|
|
{
|
|
}
|
|
|
|
public BB(int f, int g)
|
|
: base(f)
|
|
{
|
|
BB_field1 = g;
|
|
BB_field2 = g;
|
|
BB_property1 = g;
|
|
BB_property2 = g;
|
|
BB_property3 = g;
|
|
BB_property4 = g;
|
|
BB_property5 = g;
|
|
BB_property6 = g;
|
|
BB_property7 = g;
|
|
BB_property8 = g;
|
|
}
|
|
}
|
|
|
|
#if !NET20 && !SILVERLIGHT
|
|
public class XNodeTestObject
|
|
{
|
|
public XDocument Document { get; set; }
|
|
public XElement Element { get; set; }
|
|
}
|
|
#endif
|
|
|
|
#if !SILVERLIGHT
|
|
public class XmlNodeTestObject
|
|
{
|
|
public XmlDocument Document { get; set; }
|
|
}
|
|
#endif
|
|
|
|
#if !NET20 && !SILVERLIGHT
|
|
[Test]
|
|
public void SerializeDeserializeXNodeProperties()
|
|
{
|
|
XNodeTestObject testObject = new XNodeTestObject();
|
|
testObject.Document = XDocument.Parse("<root>hehe, root</root>");
|
|
testObject.Element = XElement.Parse(@"<fifth xmlns:json=""http://json.org"" json:Awesome=""true"">element</fifth>");
|
|
|
|
string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
|
|
string expected = @"{
|
|
""Document"": {
|
|
""root"": ""hehe, root""
|
|
},
|
|
""Element"": {
|
|
""fifth"": {
|
|
""@xmlns:json"": ""http://json.org"",
|
|
""@json:Awesome"": ""true"",
|
|
""#text"": ""element""
|
|
}
|
|
}
|
|
}";
|
|
Assert.AreEqual(expected, json);
|
|
|
|
XNodeTestObject newTestObject = JsonConvert.DeserializeObject<XNodeTestObject>(json);
|
|
Assert.AreEqual(testObject.Document.ToString(), newTestObject.Document.ToString());
|
|
Assert.AreEqual(testObject.Element.ToString(), newTestObject.Element.ToString());
|
|
|
|
Assert.IsNull(newTestObject.Element.Parent);
|
|
}
|
|
#endif
|
|
|
|
#if !SILVERLIGHT
|
|
[Test]
|
|
public void SerializeDeserializeXmlNodeProperties()
|
|
{
|
|
XmlNodeTestObject testObject = new XmlNodeTestObject();
|
|
XmlDocument document = new XmlDocument();
|
|
document.LoadXml("<root>hehe, root</root>");
|
|
testObject.Document = document;
|
|
|
|
string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
|
|
string expected = @"{
|
|
""Document"": {
|
|
""root"": ""hehe, root""
|
|
}
|
|
}";
|
|
Assert.AreEqual(expected, json);
|
|
|
|
XmlNodeTestObject newTestObject = JsonConvert.DeserializeObject<XmlNodeTestObject>(json);
|
|
Assert.AreEqual(testObject.Document.InnerXml, newTestObject.Document.InnerXml);
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void FullClientMapSerialization()
|
|
{
|
|
ClientMap source = new ClientMap()
|
|
{
|
|
position = new Pos() {X = 100, Y = 200},
|
|
center = new PosDouble() {X = 251.6, Y = 361.3}
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter());
|
|
Assert.AreEqual("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}", json);
|
|
}
|
|
|
|
public class ClientMap
|
|
{
|
|
public Pos position { get; set; }
|
|
public PosDouble center { get; set; }
|
|
}
|
|
|
|
public class Pos
|
|
{
|
|
public int X { get; set; }
|
|
public int Y { get; set; }
|
|
}
|
|
|
|
public class PosDouble
|
|
{
|
|
public double X { get; set; }
|
|
public double Y { get; set; }
|
|
}
|
|
|
|
public class PosConverter : JsonConverter
|
|
{
|
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
{
|
|
Pos p = (Pos) value;
|
|
|
|
if (p != null)
|
|
writer.WriteRawValue(String.Format("new Pos({0},{1})", p.X, p.Y));
|
|
else
|
|
writer.WriteNull();
|
|
}
|
|
|
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override bool CanConvert(Type objectType)
|
|
{
|
|
return objectType.IsAssignableFrom(typeof (Pos));
|
|
}
|
|
}
|
|
|
|
public class PosDoubleConverter : JsonConverter
|
|
{
|
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
{
|
|
PosDouble p = (PosDouble) value;
|
|
|
|
if (p != null)
|
|
writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y));
|
|
else
|
|
writer.WriteNull();
|
|
}
|
|
|
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override bool CanConvert(Type objectType)
|
|
{
|
|
return objectType.IsAssignableFrom(typeof (PosDouble));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestEscapeDictionaryStrings()
|
|
{
|
|
const string s = @"host\user";
|
|
string serialized = JsonConvert.SerializeObject(s);
|
|
Assert.AreEqual(@"""host\\user""", serialized);
|
|
|
|
Dictionary<int, object> d1 = new Dictionary<int, object>();
|
|
d1.Add(5, s);
|
|
Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1));
|
|
|
|
Dictionary<string, object> d2 = new Dictionary<string, object>();
|
|
d2.Add(s, 5);
|
|
Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2));
|
|
}
|
|
|
|
public class GenericListTestClass
|
|
{
|
|
public List<string> GenericList { get; set; }
|
|
|
|
public GenericListTestClass()
|
|
{
|
|
GenericList = new List<string>();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeExistingGenericList()
|
|
{
|
|
GenericListTestClass c = new GenericListTestClass();
|
|
c.GenericList.Add("1");
|
|
c.GenericList.Add("2");
|
|
|
|
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
GenericListTestClass newValue = JsonConvert.DeserializeObject<GenericListTestClass>(json);
|
|
Assert.AreEqual(2, newValue.GenericList.Count);
|
|
Assert.AreEqual(typeof (List<string>), newValue.GenericList.GetType());
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeSimpleKeyValuePair()
|
|
{
|
|
List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
|
|
list.Add(new KeyValuePair<string, string>("key1", "value1"));
|
|
list.Add(new KeyValuePair<string, string>("key2", "value2"));
|
|
|
|
string json = JsonConvert.SerializeObject(list);
|
|
|
|
Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json);
|
|
|
|
List<KeyValuePair<string, string>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, string>>>(json);
|
|
Assert.AreEqual(2, result.Count);
|
|
Assert.AreEqual("key1", result[0].Key);
|
|
Assert.AreEqual("value1", result[0].Value);
|
|
Assert.AreEqual("key2", result[1].Key);
|
|
Assert.AreEqual("value2", result[1].Value);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeComplexKeyValuePair()
|
|
{
|
|
DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc);
|
|
|
|
List<KeyValuePair<string, WagePerson>> list = new List<KeyValuePair<string, WagePerson>>();
|
|
list.Add(new KeyValuePair<string, WagePerson>("key1", new WagePerson
|
|
{
|
|
BirthDate = dateTime,
|
|
Department = "Department1",
|
|
LastModified = dateTime,
|
|
HourlyWage = 1
|
|
}));
|
|
list.Add(new KeyValuePair<string, WagePerson>("key2", new WagePerson
|
|
{
|
|
BirthDate = dateTime,
|
|
Department = "Department2",
|
|
LastModified = dateTime,
|
|
HourlyWage = 2
|
|
}));
|
|
|
|
string json = JsonConvert.SerializeObject(list, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"[
|
|
{
|
|
""Key"": ""key1"",
|
|
""Value"": {
|
|
""HourlyWage"": 1.0,
|
|
""Name"": null,
|
|
""BirthDate"": ""\/Date(975711661000)\/"",
|
|
""LastModified"": ""\/Date(975711661000)\/""
|
|
}
|
|
},
|
|
{
|
|
""Key"": ""key2"",
|
|
""Value"": {
|
|
""HourlyWage"": 2.0,
|
|
""Name"": null,
|
|
""BirthDate"": ""\/Date(975711661000)\/"",
|
|
""LastModified"": ""\/Date(975711661000)\/""
|
|
}
|
|
}
|
|
]", json);
|
|
|
|
List<KeyValuePair<string, WagePerson>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, WagePerson>>>(json);
|
|
Assert.AreEqual(2, result.Count);
|
|
Assert.AreEqual("key1", result[0].Key);
|
|
Assert.AreEqual(1, result[0].Value.HourlyWage);
|
|
Assert.AreEqual("key2", result[1].Key);
|
|
Assert.AreEqual(2, result[1].Value.HourlyWage);
|
|
}
|
|
|
|
public class StringListAppenderConverter : JsonConverter
|
|
{
|
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
{
|
|
writer.WriteValue(value);
|
|
}
|
|
|
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
{
|
|
List<string> existingStrings = (List<string>) existingValue;
|
|
List<string> newStrings = new List<string>(existingStrings);
|
|
|
|
reader.Read();
|
|
|
|
while (reader.TokenType != JsonToken.EndArray)
|
|
{
|
|
string s = (string) reader.Value;
|
|
newStrings.Add(s);
|
|
|
|
reader.Read();
|
|
}
|
|
|
|
return newStrings;
|
|
}
|
|
|
|
public override bool CanConvert(Type objectType)
|
|
{
|
|
return (objectType == typeof (List<string>));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void StringListAppenderConverterTest()
|
|
{
|
|
Movie p = new Movie();
|
|
p.ReleaseCountries = new List<string> {"Existing"};
|
|
|
|
JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings
|
|
{
|
|
Converters = new List<JsonConverter> {new StringListAppenderConverter()}
|
|
});
|
|
|
|
Assert.AreEqual(2, p.ReleaseCountries.Count);
|
|
Assert.AreEqual("Existing", p.ReleaseCountries[0]);
|
|
Assert.AreEqual("Appended", p.ReleaseCountries[1]);
|
|
}
|
|
|
|
public class StringAppenderConverter : JsonConverter
|
|
{
|
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
{
|
|
writer.WriteValue(value);
|
|
}
|
|
|
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
{
|
|
string existingString = (string) existingValue;
|
|
string newString = existingString + (string) reader.Value;
|
|
|
|
return newString;
|
|
}
|
|
|
|
public override bool CanConvert(Type objectType)
|
|
{
|
|
return (objectType == typeof (string));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void StringAppenderConverterTest()
|
|
{
|
|
Movie p = new Movie();
|
|
p.Name = "Existing,";
|
|
|
|
JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings
|
|
{
|
|
Converters = new List<JsonConverter> {new StringAppenderConverter()}
|
|
});
|
|
|
|
Assert.AreEqual("Existing,Appended", p.Name);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Additional content found in JSON reference object. A JSON reference object should only have a $ref property. Line 6, position 11.")]
|
|
public void SerializeRefAdditionalContent()
|
|
{
|
|
//Additional text found in JSON string after finishing deserializing object.
|
|
//Test 1
|
|
var reference = new Dictionary<string, object>();
|
|
reference.Add("$ref", "Persons");
|
|
reference.Add("$id", 1);
|
|
|
|
var child = new Dictionary<string, object>();
|
|
child.Add("_id", 2);
|
|
child.Add("Name", "Isabell");
|
|
child.Add("Father", reference);
|
|
|
|
var json = JsonConvert.SerializeObject(child, Formatting.Indented);
|
|
JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "JSON reference $ref property must have a string or null value. Line 5, position 14.")]
|
|
public void SerializeRefBadType()
|
|
{
|
|
//Additional text found in JSON string after finishing deserializing object.
|
|
//Test 1
|
|
var reference = new Dictionary<string, object>();
|
|
reference.Add("$ref", 1);
|
|
reference.Add("$id", 1);
|
|
|
|
var child = new Dictionary<string, object>();
|
|
child.Add("_id", 2);
|
|
child.Add("Name", "Isabell");
|
|
child.Add("Father", reference);
|
|
|
|
var json = JsonConvert.SerializeObject(child, Formatting.Indented);
|
|
JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeRefNull()
|
|
{
|
|
var reference = new Dictionary<string, object>();
|
|
reference.Add("$ref", null);
|
|
reference.Add("$id", null);
|
|
reference.Add("blah", "blah!");
|
|
|
|
var child = new Dictionary<string, object>();
|
|
child.Add("_id", 2);
|
|
child.Add("Name", "Isabell");
|
|
child.Add("Father", reference);
|
|
|
|
var json = JsonConvert.SerializeObject(child);
|
|
Dictionary<string, object> result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
|
|
|
|
Assert.AreEqual(3, result.Count);
|
|
Assert.AreEqual(1, ((JObject) result["Father"]).Count);
|
|
Assert.AreEqual("blah!", (string) ((JObject) result["Father"])["blah"]);
|
|
}
|
|
|
|
public class ConstructorCompexIgnoredProperty
|
|
{
|
|
[JsonIgnore]
|
|
public Product Ignored { get; set; }
|
|
|
|
public string First { get; set; }
|
|
public int Second { get; set; }
|
|
|
|
public ConstructorCompexIgnoredProperty(string first, int second)
|
|
{
|
|
First = first;
|
|
Second = second;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeIgnoredPropertyInConstructor()
|
|
{
|
|
string json = @"{""First"":""First"",""Second"":2,""Ignored"":{""Name"":""James""},""AdditionalContent"":{""LOL"":true}}";
|
|
|
|
ConstructorCompexIgnoredProperty cc = JsonConvert.DeserializeObject<ConstructorCompexIgnoredProperty>(json);
|
|
Assert.AreEqual("First", cc.First);
|
|
Assert.AreEqual(2, cc.Second);
|
|
Assert.AreEqual(null, cc.Ignored);
|
|
}
|
|
|
|
public class ShouldSerializeTestClass
|
|
{
|
|
internal bool _shouldSerializeName;
|
|
|
|
public string Name { get; set; }
|
|
public int Age { get; set; }
|
|
|
|
public void ShouldSerializeAge()
|
|
{
|
|
// dummy. should never be used because it doesn't return bool
|
|
}
|
|
|
|
public bool ShouldSerializeName()
|
|
{
|
|
return _shouldSerializeName;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ShouldSerializeTest()
|
|
{
|
|
ShouldSerializeTestClass c = new ShouldSerializeTestClass();
|
|
c.Name = "James";
|
|
c.Age = 27;
|
|
|
|
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Age"": 27
|
|
}", json);
|
|
|
|
c._shouldSerializeName = true;
|
|
json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Name"": ""James"",
|
|
""Age"": 27
|
|
}", json);
|
|
|
|
ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject<ShouldSerializeTestClass>(json);
|
|
Assert.AreEqual("James", deserialized.Name);
|
|
Assert.AreEqual(27, deserialized.Age);
|
|
}
|
|
|
|
public class Employee
|
|
{
|
|
public string Name { get; set; }
|
|
public Employee Manager { get; set; }
|
|
|
|
public bool ShouldSerializeManager()
|
|
{
|
|
return (Manager != this);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ShouldSerializeExample()
|
|
{
|
|
Employee joe = new Employee();
|
|
joe.Name = "Joe Employee";
|
|
Employee mike = new Employee();
|
|
mike.Name = "Mike Manager";
|
|
|
|
joe.Manager = mike;
|
|
mike.Manager = mike;
|
|
|
|
string json = JsonConvert.SerializeObject(new[] {joe, mike}, Formatting.Indented);
|
|
// [
|
|
// {
|
|
// "Name": "Joe Employee",
|
|
// "Manager": {
|
|
// "Name": "Mike Manager"
|
|
// }
|
|
// },
|
|
// {
|
|
// "Name": "Mike Manager"
|
|
// }
|
|
// ]
|
|
|
|
Console.WriteLine(json);
|
|
}
|
|
|
|
public class SpecifiedTestClass
|
|
{
|
|
private bool _nameSpecified;
|
|
|
|
public string Name { get; set; }
|
|
public int Age { get; set; }
|
|
public int Weight { get; set; }
|
|
public int Height { get; set; }
|
|
public int FavoriteNumber { get; set; }
|
|
|
|
// dummy. should never be used because it isn't of type bool
|
|
[JsonIgnore]
|
|
public long AgeSpecified { get; set; }
|
|
|
|
[JsonIgnore]
|
|
public bool NameSpecified
|
|
{
|
|
get { return _nameSpecified; }
|
|
set { _nameSpecified = value; }
|
|
}
|
|
|
|
[JsonIgnore] public bool WeightSpecified;
|
|
|
|
[JsonIgnore] [System.Xml.Serialization.XmlIgnoreAttribute] public bool HeightSpecified;
|
|
|
|
[JsonIgnore]
|
|
|
|
public bool FavoriteNumberSpecified
|
|
{
|
|
// get only example
|
|
get { return FavoriteNumber != 0; }
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SpecifiedTest()
|
|
{
|
|
SpecifiedTestClass c = new SpecifiedTestClass();
|
|
c.Name = "James";
|
|
c.Age = 27;
|
|
c.NameSpecified = false;
|
|
|
|
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Age"": 27
|
|
}", json);
|
|
|
|
SpecifiedTestClass deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
|
|
Assert.IsNull(deserialized.Name);
|
|
Assert.IsFalse(deserialized.NameSpecified);
|
|
Assert.IsFalse(deserialized.WeightSpecified);
|
|
Assert.IsFalse(deserialized.HeightSpecified);
|
|
Assert.IsFalse(deserialized.FavoriteNumberSpecified);
|
|
Assert.AreEqual(27, deserialized.Age);
|
|
|
|
c.NameSpecified = true;
|
|
c.WeightSpecified = true;
|
|
c.HeightSpecified = true;
|
|
c.FavoriteNumber = 23;
|
|
json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Name"": ""James"",
|
|
""Age"": 27,
|
|
""Weight"": 0,
|
|
""Height"": 0,
|
|
""FavoriteNumber"": 23
|
|
}", json);
|
|
|
|
deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
|
|
Assert.AreEqual("James", deserialized.Name);
|
|
Assert.IsTrue(deserialized.NameSpecified);
|
|
Assert.IsTrue(deserialized.WeightSpecified);
|
|
Assert.IsTrue(deserialized.HeightSpecified);
|
|
Assert.IsTrue(deserialized.FavoriteNumberSpecified);
|
|
Assert.AreEqual(27, deserialized.Age);
|
|
Assert.AreEqual(23, deserialized.FavoriteNumber);
|
|
}
|
|
|
|
// [Test]
|
|
// public void XmlSerializerSpecifiedTrueTest()
|
|
// {
|
|
// XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
|
|
|
|
// StringWriter sw = new StringWriter();
|
|
// s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true });
|
|
|
|
// Console.WriteLine(sw.ToString());
|
|
|
|
// string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
|
|
//<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
|
|
// <FirstOrder>First</FirstOrder>
|
|
//</OptionalOrder>";
|
|
|
|
// OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
|
|
// Console.WriteLine(o.FirstOrder);
|
|
// Console.WriteLine(o.FirstOrderSpecified);
|
|
// }
|
|
|
|
// [Test]
|
|
// public void XmlSerializerSpecifiedFalseTest()
|
|
// {
|
|
// XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
|
|
|
|
// StringWriter sw = new StringWriter();
|
|
// s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false });
|
|
|
|
// Console.WriteLine(sw.ToString());
|
|
|
|
// // string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
|
|
// //<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
|
|
// // <FirstOrder>First</FirstOrder>
|
|
// //</OptionalOrder>";
|
|
|
|
// // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
|
|
// // Console.WriteLine(o.FirstOrder);
|
|
// // Console.WriteLine(o.FirstOrderSpecified);
|
|
// }
|
|
|
|
public class OptionalOrder
|
|
{
|
|
// This field shouldn't be serialized
|
|
// if it is uninitialized.
|
|
public string FirstOrder;
|
|
// Use the XmlIgnoreAttribute to ignore the
|
|
// special field named "FirstOrderSpecified".
|
|
[System.Xml.Serialization.XmlIgnoreAttribute] public bool FirstOrderSpecified;
|
|
}
|
|
|
|
public class FamilyDetails
|
|
{
|
|
public string Name { get; set; }
|
|
public int NumberOfChildren { get; set; }
|
|
|
|
[JsonIgnore]
|
|
public bool NumberOfChildrenSpecified { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void SpecifiedExample()
|
|
{
|
|
FamilyDetails joe = new FamilyDetails();
|
|
joe.Name = "Joe Family Details";
|
|
joe.NumberOfChildren = 4;
|
|
joe.NumberOfChildrenSpecified = true;
|
|
|
|
FamilyDetails martha = new FamilyDetails();
|
|
martha.Name = "Martha Family Details";
|
|
martha.NumberOfChildren = 3;
|
|
martha.NumberOfChildrenSpecified = false;
|
|
|
|
string json = JsonConvert.SerializeObject(new[] {joe, martha}, Formatting.Indented);
|
|
//[
|
|
// {
|
|
// "Name": "Joe Family Details",
|
|
// "NumberOfChildren": 4
|
|
// },
|
|
// {
|
|
// "Name": "Martha Family Details"
|
|
// }
|
|
//]
|
|
Console.WriteLine(json);
|
|
|
|
string mikeString = "{\"Name\": \"Mike Person\"}";
|
|
FamilyDetails mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeString);
|
|
|
|
Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
|
|
|
|
string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}";
|
|
mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeFullDisclosureString);
|
|
|
|
Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
|
|
}
|
|
|
|
public class DictionaryKey
|
|
{
|
|
public string Value { get; set; }
|
|
|
|
public override string ToString()
|
|
{
|
|
return Value;
|
|
}
|
|
|
|
public static implicit operator DictionaryKey(string value)
|
|
{
|
|
return new DictionaryKey() {Value = value};
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeDeserializeDictionaryKey()
|
|
{
|
|
Dictionary<DictionaryKey, string> dictionary = new Dictionary<DictionaryKey, string>();
|
|
|
|
dictionary.Add(new DictionaryKey() {Value = "First!"}, "First");
|
|
dictionary.Add(new DictionaryKey() {Value = "Second!"}, "Second");
|
|
|
|
string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""First!"": ""First"",
|
|
""Second!"": ""Second""
|
|
}", json);
|
|
|
|
Dictionary<DictionaryKey, string> newDictionary =
|
|
JsonConvert.DeserializeObject<Dictionary<DictionaryKey, string>>(json);
|
|
|
|
Assert.AreEqual(2, newDictionary.Count);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeNullableArray()
|
|
{
|
|
string jsonText = JsonConvert.SerializeObject(new double?[] {2.4, 4.3, null}, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"[
|
|
2.4,
|
|
4.3,
|
|
null
|
|
]", jsonText);
|
|
|
|
double?[] d = (double?[]) JsonConvert.DeserializeObject(jsonText, typeof (double?[]));
|
|
|
|
Assert.AreEqual(3, d.Length);
|
|
Assert.AreEqual(2.4, d[0]);
|
|
Assert.AreEqual(4.3, d[1]);
|
|
Assert.AreEqual(null, d[2]);
|
|
}
|
|
|
|
#if !SILVERLIGHT && !NET20 && !PocketPC
|
|
[Test]
|
|
public void SerializeHashSet()
|
|
{
|
|
string jsonText = JsonConvert.SerializeObject(new HashSet<string>()
|
|
{
|
|
"One",
|
|
"2",
|
|
"III"
|
|
}, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"[
|
|
""One"",
|
|
""2"",
|
|
""III""
|
|
]", jsonText);
|
|
|
|
HashSet<string> d = JsonConvert.DeserializeObject<HashSet<string>>(jsonText);
|
|
|
|
Assert.AreEqual(3, d.Count);
|
|
Assert.IsTrue(d.Contains("One"));
|
|
Assert.IsTrue(d.Contains("2"));
|
|
Assert.IsTrue(d.Contains("III"));
|
|
}
|
|
#endif
|
|
|
|
private class MyClass
|
|
{
|
|
public byte[] Prop1 { get; set; }
|
|
|
|
public MyClass()
|
|
{
|
|
Prop1 = new byte[0];
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeByteArray()
|
|
{
|
|
JsonSerializer serializer1 = new JsonSerializer();
|
|
serializer1.Converters.Add(new IsoDateTimeConverter());
|
|
serializer1.NullValueHandling = NullValueHandling.Ignore;
|
|
|
|
string json = @"[{""Prop1"":""""},{""Prop1"":""""}]";
|
|
|
|
JsonTextReader reader = new JsonTextReader(new StringReader(json));
|
|
|
|
MyClass[] z = (MyClass[]) serializer1.Deserialize(reader, typeof (MyClass[]));
|
|
Assert.AreEqual(2, z.Length);
|
|
Assert.AreEqual(0, z[0].Prop1.Length);
|
|
Assert.AreEqual(0, z[1].Prop1.Length);
|
|
}
|
|
|
|
#if !NET20 && !PocketPC && !SILVERLIGHT
|
|
public class StringDictionaryTestClass
|
|
{
|
|
public StringDictionary StringDictionaryProperty { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (Exception), ExpectedMessage = "Cannot create and populate list type System.Collections.Specialized.StringDictionary.")]
|
|
public void StringDictionaryTest()
|
|
{
|
|
StringDictionaryTestClass s1 = new StringDictionaryTestClass()
|
|
{
|
|
StringDictionaryProperty = new StringDictionary()
|
|
{
|
|
{"1", "One"},
|
|
{"2", "II"},
|
|
{"3", "3"}
|
|
}
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(s1, Formatting.Indented);
|
|
|
|
JsonConvert.DeserializeObject<StringDictionaryTestClass>(json);
|
|
}
|
|
#endif
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public struct StructWithAttribute
|
|
{
|
|
public string MyString { get; set; }
|
|
|
|
[JsonProperty]
|
|
public int MyInt { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeStructWithJsonObjectAttribute()
|
|
{
|
|
StructWithAttribute testStruct = new StructWithAttribute
|
|
{
|
|
MyInt = int.MaxValue
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""MyInt"": 2147483647
|
|
}", json);
|
|
|
|
StructWithAttribute newStruct = JsonConvert.DeserializeObject<StructWithAttribute>(json);
|
|
|
|
Assert.AreEqual(int.MaxValue, newStruct.MyInt);
|
|
}
|
|
|
|
public class TimeZoneOffsetObject
|
|
{
|
|
public DateTimeOffset Offset { get; set; }
|
|
}
|
|
|
|
#if !NET20
|
|
[Test]
|
|
public void ReadWriteTimeZoneOffset()
|
|
{
|
|
var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject
|
|
{
|
|
Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6))
|
|
});
|
|
|
|
Assert.AreEqual("{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}", serializeObject);
|
|
var deserializeObject = JsonConvert.DeserializeObject<TimeZoneOffsetObject>(serializeObject);
|
|
Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset);
|
|
Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializePropertyNullableDateTimeOffsetExact()
|
|
{
|
|
NullableDateTimeTestClass d = JsonConvert.DeserializeObject<NullableDateTimeTestClass>("{\"DateTimeOffsetField\":\"\\/Date(946663200000+0600)\\/\"}");
|
|
Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField);
|
|
}
|
|
#endif
|
|
|
|
public abstract class LogEvent
|
|
{
|
|
[JsonProperty("event")]
|
|
public abstract string EventName { get; }
|
|
}
|
|
|
|
public class DerivedEvent : LogEvent
|
|
{
|
|
public override string EventName
|
|
{
|
|
get { return "derived"; }
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void OverridenPropertyMembers()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new DerivedEvent(), Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""event"": ""derived""
|
|
}", json);
|
|
}
|
|
|
|
#if !(NET35 || NET20 || WINDOWS_PHONE)
|
|
[Test]
|
|
public void SerializeExpandoObject()
|
|
{
|
|
dynamic expando = new ExpandoObject();
|
|
expando.Int = 1;
|
|
expando.Decimal = 99.9d;
|
|
expando.Complex = new ExpandoObject();
|
|
expando.Complex.String = "I am a string";
|
|
expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc);
|
|
|
|
string json = JsonConvert.SerializeObject(expando, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""Int"": 1,
|
|
""Decimal"": 99.9,
|
|
""Complex"": {
|
|
""String"": ""I am a string"",
|
|
""DateTime"": ""\/Date(977338500000)\/""
|
|
}
|
|
}", json);
|
|
|
|
IDictionary<string, object> newExpando = JsonConvert.DeserializeObject<ExpandoObject>(json);
|
|
|
|
Assert.IsInstanceOfType(typeof (long), newExpando["Int"]);
|
|
Assert.AreEqual(expando.Int, newExpando["Int"]);
|
|
|
|
Assert.IsInstanceOfType(typeof (double), newExpando["Decimal"]);
|
|
Assert.AreEqual(expando.Decimal, newExpando["Decimal"]);
|
|
|
|
Assert.IsInstanceOfType(typeof (ExpandoObject), newExpando["Complex"]);
|
|
IDictionary<string, object> o = (ExpandoObject) newExpando["Complex"];
|
|
|
|
Assert.IsInstanceOfType(typeof (string), o["String"]);
|
|
Assert.AreEqual(expando.Complex.String, o["String"]);
|
|
|
|
Assert.IsInstanceOfType(typeof (DateTime), o["DateTime"]);
|
|
Assert.AreEqual(expando.Complex.DateTime, o["DateTime"]);
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void DeserializeDecimalExact()
|
|
{
|
|
decimal d = JsonConvert.DeserializeObject<decimal>("123456789876543.21");
|
|
Assert.AreEqual(123456789876543.21m, d);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullableDecimalExact()
|
|
{
|
|
decimal? d = JsonConvert.DeserializeObject<decimal?>("123456789876543.21");
|
|
Assert.AreEqual(123456789876543.21m, d);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeDecimalPropertyExact()
|
|
{
|
|
string json = "{Amount:123456789876543.21}";
|
|
Invoice i = JsonConvert.DeserializeObject<Invoice>(json);
|
|
Assert.AreEqual(123456789876543.21m, i.Amount);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeDecimalArrayExact()
|
|
{
|
|
string json = "[123456789876543.21]";
|
|
IList<decimal> a = JsonConvert.DeserializeObject<IList<decimal>>(json);
|
|
Assert.AreEqual(123456789876543.21m, a[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeDecimalDictionaryExact()
|
|
{
|
|
string json = "{'Value':123456789876543.21}";
|
|
IDictionary<string, decimal> d = JsonConvert.DeserializeObject<IDictionary<string, decimal>>(json);
|
|
Assert.AreEqual(123456789876543.21m, d["Value"]);
|
|
}
|
|
|
|
public struct Vector
|
|
{
|
|
public float X;
|
|
public float Y;
|
|
public float Z;
|
|
|
|
public override string ToString()
|
|
{
|
|
return string.Format("({0},{1},{2})", X, Y, Z);
|
|
}
|
|
}
|
|
|
|
public class VectorParent
|
|
{
|
|
public Vector Position;
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeStructProperty()
|
|
{
|
|
VectorParent obj = new VectorParent();
|
|
obj.Position = new Vector {X = 1, Y = 2, Z = 3};
|
|
|
|
string str = JsonConvert.SerializeObject(obj);
|
|
|
|
obj = JsonConvert.DeserializeObject<VectorParent>(str);
|
|
|
|
Assert.AreEqual(1, obj.Position.X);
|
|
Assert.AreEqual(2, obj.Position.Y);
|
|
Assert.AreEqual(3, obj.Position.Z);
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class Derived : Base
|
|
{
|
|
[JsonProperty]
|
|
public string IDoWork { get; private set; }
|
|
|
|
private Derived()
|
|
{
|
|
}
|
|
|
|
internal Derived(string dontWork, string doWork)
|
|
: base(dontWork)
|
|
{
|
|
IDoWork = doWork;
|
|
}
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class Base
|
|
{
|
|
[JsonProperty]
|
|
public string IDontWork { get; private set; }
|
|
|
|
protected Base()
|
|
{
|
|
}
|
|
|
|
internal Base(string dontWork)
|
|
{
|
|
IDontWork = dontWork;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void PrivateSetterOnBaseClassProperty()
|
|
{
|
|
var derived = new Derived("meh", "woo");
|
|
|
|
var settings = new JsonSerializerSettings
|
|
{
|
|
TypeNameHandling = TypeNameHandling.Objects,
|
|
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings);
|
|
|
|
var meh = JsonConvert.DeserializeObject<Base>(json, settings);
|
|
|
|
Assert.AreEqual(((Derived) meh).IDoWork, "woo");
|
|
Assert.AreEqual(meh.IDontWork, "meh");
|
|
}
|
|
|
|
#if !(SILVERLIGHT || PocketPC || NET20)
|
|
[DataContract]
|
|
public struct StructISerializable : ISerializable
|
|
{
|
|
private string _name;
|
|
|
|
public StructISerializable(SerializationInfo info, StreamingContext context)
|
|
{
|
|
_name = info.GetString("Name");
|
|
}
|
|
|
|
[DataMember]
|
|
public string Name
|
|
{
|
|
get { return _name; }
|
|
set { _name = value; }
|
|
}
|
|
|
|
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
|
{
|
|
info.AddValue("Name", _name);
|
|
}
|
|
}
|
|
|
|
[DataContract]
|
|
public class NullableStructPropertyClass
|
|
{
|
|
private StructISerializable _foo1;
|
|
private StructISerializable? _foo2;
|
|
|
|
[DataMember]
|
|
public StructISerializable Foo1
|
|
{
|
|
get { return _foo1; }
|
|
set { _foo1 = value; }
|
|
}
|
|
|
|
[DataMember]
|
|
public StructISerializable? Foo2
|
|
{
|
|
get { return _foo2; }
|
|
set { _foo2 = value; }
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullableStruct()
|
|
{
|
|
NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass();
|
|
nullableStructPropertyClass.Foo1 = new StructISerializable() {Name = "foo 1"};
|
|
nullableStructPropertyClass.Foo2 = new StructISerializable() {Name = "foo 2"};
|
|
|
|
NullableStructPropertyClass barWithNull = new NullableStructPropertyClass();
|
|
barWithNull.Foo1 = new StructISerializable() {Name = "foo 1"};
|
|
barWithNull.Foo2 = null;
|
|
|
|
//throws error on deserialization because bar1.Foo2 is of type Foo?
|
|
string s = JsonConvert.SerializeObject(nullableStructPropertyClass);
|
|
NullableStructPropertyClass deserialized = deserialize(s);
|
|
Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
|
|
Assert.AreEqual(deserialized.Foo2.Value.Name, "foo 2");
|
|
|
|
//no error Foo2 is null
|
|
s = JsonConvert.SerializeObject(barWithNull);
|
|
deserialized = deserialize(s);
|
|
Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
|
|
Assert.AreEqual(deserialized.Foo2, null);
|
|
}
|
|
|
|
|
|
private static NullableStructPropertyClass deserialize(string serStr)
|
|
{
|
|
return JsonConvert.DeserializeObject<NullableStructPropertyClass>(
|
|
serStr,
|
|
new JsonSerializerSettings
|
|
{
|
|
NullValueHandling = NullValueHandling.Ignore,
|
|
MissingMemberHandling = MissingMemberHandling.Ignore
|
|
});
|
|
}
|
|
#endif
|
|
|
|
public class Response
|
|
{
|
|
public string Name { get; set; }
|
|
public JToken Data { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeJToken()
|
|
{
|
|
Response response = new Response
|
|
{
|
|
Name = "Success",
|
|
Data = new JObject(new JProperty("First", "Value1"), new JProperty("Second", "Value2"))
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(response, Formatting.Indented);
|
|
|
|
Response deserializedResponse = JsonConvert.DeserializeObject<Response>(json);
|
|
|
|
Assert.AreEqual("Success", deserializedResponse.Name);
|
|
Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data));
|
|
}
|
|
|
|
public abstract class Test<T>
|
|
{
|
|
public abstract T Value { get; set; }
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class DecimalTest : Test<decimal>
|
|
{
|
|
protected DecimalTest()
|
|
{
|
|
}
|
|
|
|
public DecimalTest(decimal val)
|
|
{
|
|
Value = val;
|
|
}
|
|
|
|
[JsonProperty]
|
|
public override decimal Value { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void OnError()
|
|
{
|
|
var data = new DecimalTest(decimal.MinValue);
|
|
var json = JsonConvert.SerializeObject(data);
|
|
var obj = JsonConvert.DeserializeObject<DecimalTest>(json);
|
|
|
|
Assert.AreEqual(decimal.MinValue, obj.Value);
|
|
}
|
|
|
|
public class NonPublicConstructorWithJsonConstructor
|
|
{
|
|
public string Value { get; private set; }
|
|
public string Constructor { get; private set; }
|
|
|
|
[JsonConstructor]
|
|
private NonPublicConstructorWithJsonConstructor()
|
|
{
|
|
Constructor = "NonPublic";
|
|
}
|
|
|
|
public NonPublicConstructorWithJsonConstructor(string value)
|
|
{
|
|
Value = value;
|
|
Constructor = "Public Paramatized";
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void NonPublicConstructorWithJsonConstructorTest()
|
|
{
|
|
NonPublicConstructorWithJsonConstructor c = JsonConvert.DeserializeObject<NonPublicConstructorWithJsonConstructor>("{}");
|
|
Assert.AreEqual("NonPublic", c.Constructor);
|
|
}
|
|
|
|
public class PublicConstructorOverridenByJsonConstructor
|
|
{
|
|
public string Value { get; private set; }
|
|
public string Constructor { get; private set; }
|
|
|
|
public PublicConstructorOverridenByJsonConstructor()
|
|
{
|
|
Constructor = "NonPublic";
|
|
}
|
|
|
|
[JsonConstructor]
|
|
public PublicConstructorOverridenByJsonConstructor(string value)
|
|
{
|
|
Value = value;
|
|
Constructor = "Public Paramatized";
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void PublicConstructorOverridenByJsonConstructorTest()
|
|
{
|
|
PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject<PublicConstructorOverridenByJsonConstructor>("{Value:'value!'}");
|
|
Assert.AreEqual("Public Paramatized", c.Constructor);
|
|
Assert.AreEqual("value!", c.Value);
|
|
}
|
|
|
|
public class MultipleParamatrizedConstructorsJsonConstructor
|
|
{
|
|
public string Value { get; private set; }
|
|
public int Age { get; private set; }
|
|
public string Constructor { get; private set; }
|
|
|
|
public MultipleParamatrizedConstructorsJsonConstructor(string value)
|
|
{
|
|
Value = value;
|
|
Constructor = "Public Paramatized 1";
|
|
}
|
|
|
|
[JsonConstructor]
|
|
public MultipleParamatrizedConstructorsJsonConstructor(string value, int age)
|
|
{
|
|
Value = value;
|
|
Age = age;
|
|
Constructor = "Public Paramatized 2";
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void MultipleParamatrizedConstructorsJsonConstructorTest()
|
|
{
|
|
MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject<MultipleParamatrizedConstructorsJsonConstructor>("{Value:'value!', Age:1}");
|
|
Assert.AreEqual("Public Paramatized 2", c.Constructor);
|
|
Assert.AreEqual("value!", c.Value);
|
|
Assert.AreEqual(1, c.Age);
|
|
}
|
|
|
|
public class EnumerableClass
|
|
{
|
|
public IEnumerable<string> Enumerable { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeEnumerable()
|
|
{
|
|
EnumerableClass c = new EnumerableClass
|
|
{
|
|
Enumerable = new List<string> {"One", "Two", "Three"}
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Enumerable"": [
|
|
""One"",
|
|
""Two"",
|
|
""Three""
|
|
]
|
|
}", json);
|
|
|
|
EnumerableClass c2 = JsonConvert.DeserializeObject<EnumerableClass>(json);
|
|
|
|
Assert.AreEqual("One", c2.Enumerable.ElementAt(0));
|
|
Assert.AreEqual("Two", c2.Enumerable.ElementAt(1));
|
|
Assert.AreEqual("Three", c2.Enumerable.ElementAt(2));
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class ItemBase
|
|
{
|
|
[JsonProperty]
|
|
public string Name { get; set; }
|
|
}
|
|
|
|
public class ComplexItem : ItemBase
|
|
{
|
|
public Stream Source { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeAttributesOnBase()
|
|
{
|
|
ComplexItem i = new ComplexItem();
|
|
|
|
string json = JsonConvert.SerializeObject(i, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Name"": null
|
|
}", json);
|
|
}
|
|
|
|
public class DeserializeStringConvert
|
|
{
|
|
public string Name { get; set; }
|
|
public int Age { get; set; }
|
|
public double Height { get; set; }
|
|
public decimal Price { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeStringEnglish()
|
|
{
|
|
string json = @"{
|
|
'Name': 'James Hughes',
|
|
'Age': '40',
|
|
'Height': '44.4',
|
|
'Price': '4'
|
|
}";
|
|
|
|
DeserializeStringConvert p = JsonConvert.DeserializeObject<DeserializeStringConvert>(json);
|
|
Assert.AreEqual(40, p.Age);
|
|
Assert.AreEqual(44.4, p.Height);
|
|
Assert.AreEqual(4d, p.Price);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Error converting value {null} to type 'System.DateTime'. Line 1, position 4.")]
|
|
public void DeserializeNullDateTimeValueTest()
|
|
{
|
|
JsonConvert.DeserializeObject("null", typeof (DateTime));
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullNullableDateTimeValueTest()
|
|
{
|
|
object dateTime = JsonConvert.DeserializeObject("null", typeof (DateTime?));
|
|
|
|
Assert.IsNull(dateTime);
|
|
}
|
|
|
|
[Test]
|
|
public void MultiIndexSuperTest()
|
|
{
|
|
MultiIndexSuper e = new MultiIndexSuper();
|
|
|
|
string json = JsonConvert.SerializeObject(e, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{}", json);
|
|
}
|
|
|
|
public class MultiIndexSuper : MultiIndexBase
|
|
{
|
|
|
|
}
|
|
|
|
public abstract class MultiIndexBase
|
|
{
|
|
protected internal object this[string propertyName]
|
|
{
|
|
get { return null; }
|
|
set { }
|
|
}
|
|
|
|
protected internal object this[object property]
|
|
{
|
|
get { return null; }
|
|
set { }
|
|
}
|
|
}
|
|
|
|
public class CommentTestClass
|
|
{
|
|
public bool Indexed { get; set; }
|
|
public int StartYear { get; set; }
|
|
public IList<decimal> Values { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void CommentTestClassTest()
|
|
{
|
|
string json = @"{""indexed"":true, ""startYear"":1939, ""values"":
|
|
[ 3000, /* 1940-1949 */
|
|
3000, 3600, 3600, 3600, 3600, 4200, 4200, 4200, 4200, 4800, /* 1950-1959 */
|
|
4800, 4800, 4800, 4800, 4800, 4800, 6600, 6600, 7800, 7800, /* 1960-1969 */
|
|
7800, 7800, 9000, 10800, 13200, 14100, 15300, 16500, 17700, 22900, /* 1970-1979 */
|
|
25900, 29700, 32400, 35700, 37800, 39600, 42000, 43800, 45000, 48000, /* 1980-1989 */
|
|
51300, 53400, 55500, 57600, 60600, 61200, 62700, 65400, 68400, 72600, /* 1990-1999 */
|
|
76200, 80400, 84900, 87000, 87900, 90000, 94200, 97500, 102000, 106800, /* 2000-2009 */
|
|
106800, 106800] /* 2010-2011 */
|
|
}";
|
|
|
|
CommentTestClass commentTestClass = JsonConvert.DeserializeObject<CommentTestClass>(json);
|
|
|
|
Assert.AreEqual(true, commentTestClass.Indexed);
|
|
Assert.AreEqual(1939, commentTestClass.StartYear);
|
|
Assert.AreEqual(63, commentTestClass.Values.Count);
|
|
}
|
|
|
|
private class DTOWithParameterisedConstructor
|
|
{
|
|
public DTOWithParameterisedConstructor(string A)
|
|
{
|
|
this.A = A;
|
|
B = 2;
|
|
}
|
|
|
|
public string A { get; set; }
|
|
public int? B { get; set; }
|
|
}
|
|
|
|
private class DTOWithoutParameterisedConstructor
|
|
{
|
|
public DTOWithoutParameterisedConstructor()
|
|
{
|
|
B = 2;
|
|
}
|
|
|
|
public string A { get; set; }
|
|
public int? B { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void PopulationBehaviourForOmittedPropertiesIsTheSameForParameterisedConstructorAsForDefaultConstructor()
|
|
{
|
|
string json = @"{A:""Test""}";
|
|
|
|
var withoutParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithoutParameterisedConstructor>(json);
|
|
var withParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithParameterisedConstructor>(json);
|
|
Assert.AreEqual(withoutParameterisedConstructor.B, withParameterisedConstructor.B);
|
|
}
|
|
|
|
public class EnumerableArrayPropertyClass
|
|
{
|
|
public IEnumerable<int> Numbers
|
|
{
|
|
get
|
|
{
|
|
return new[] {1, 2, 3}; //fails
|
|
//return new List<int>(new[] { 1, 2, 3 }); //works
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SkipPopulatingArrayPropertyClass()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new EnumerableArrayPropertyClass());
|
|
JsonConvert.DeserializeObject<EnumerableArrayPropertyClass>(json);
|
|
}
|
|
|
|
#if !NET20
|
|
[DataContract]
|
|
public class BaseDataContract
|
|
{
|
|
[DataMember(Name = "virtualMember")]
|
|
public virtual string VirtualMember { get; set; }
|
|
|
|
[DataMember(Name = "nonVirtualMember")]
|
|
public string NonVirtualMember { get; set; }
|
|
}
|
|
|
|
public class ChildDataContract : BaseDataContract
|
|
{
|
|
public override string VirtualMember { get; set; }
|
|
public string NewMember { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void ChildDataContractTest()
|
|
{
|
|
ChildDataContract cc = new ChildDataContract
|
|
{
|
|
VirtualMember = "VirtualMember!",
|
|
NonVirtualMember = "NonVirtualMember!"
|
|
};
|
|
|
|
string result = JsonConvert.SerializeObject(cc);
|
|
Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
|
|
}
|
|
#endif
|
|
|
|
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
|
|
public class BaseObject
|
|
{
|
|
[JsonProperty(PropertyName = "virtualMember")]
|
|
public virtual string VirtualMember { get; set; }
|
|
|
|
[JsonProperty(PropertyName = "nonVirtualMember")]
|
|
public string NonVirtualMember { get; set; }
|
|
}
|
|
|
|
public class ChildObject : BaseObject
|
|
{
|
|
public override string VirtualMember { get; set; }
|
|
public string NewMember { get; set; }
|
|
}
|
|
|
|
public class ChildWithDifferentOverrideObject : BaseObject
|
|
{
|
|
[JsonProperty(PropertyName = "differentVirtualMember")]
|
|
public override string VirtualMember { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void ChildObjectTest()
|
|
{
|
|
ChildObject cc = new ChildObject
|
|
{
|
|
VirtualMember = "VirtualMember!",
|
|
NonVirtualMember = "NonVirtualMember!"
|
|
};
|
|
|
|
string result = JsonConvert.SerializeObject(cc);
|
|
Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
|
|
}
|
|
|
|
[Test]
|
|
public void ChildWithDifferentOverrideObjectTest()
|
|
{
|
|
ChildWithDifferentOverrideObject cc = new ChildWithDifferentOverrideObject
|
|
{
|
|
VirtualMember = "VirtualMember!",
|
|
NonVirtualMember = "NonVirtualMember!"
|
|
};
|
|
|
|
string result = JsonConvert.SerializeObject(cc);
|
|
Assert.AreEqual(@"{""differentVirtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
|
|
}
|
|
|
|
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
|
|
public interface IInterfaceObject
|
|
{
|
|
[JsonProperty(PropertyName = "virtualMember")]
|
|
[JsonConverter(typeof (IsoDateTimeConverter))]
|
|
DateTime InterfaceMember { get; set; }
|
|
}
|
|
|
|
public class ImplementInterfaceObject : IInterfaceObject
|
|
{
|
|
public DateTime InterfaceMember { get; set; }
|
|
public string NewMember { get; set; }
|
|
|
|
[JsonProperty(PropertyName = "newMemberWithProperty")]
|
|
public string NewMemberWithProperty { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void ImplementInterfaceObjectTest()
|
|
{
|
|
ImplementInterfaceObject cc = new ImplementInterfaceObject
|
|
{
|
|
InterfaceMember = new DateTime(2010, 12, 31, 0, 0, 0, DateTimeKind.Utc),
|
|
NewMember = "NewMember!"
|
|
};
|
|
|
|
string result = JsonConvert.SerializeObject(cc, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""virtualMember"": ""2010-12-31T00:00:00Z"",
|
|
""newMemberWithProperty"": null
|
|
}", result);
|
|
}
|
|
|
|
public class NonDefaultConstructorWithReadOnlyCollectionProperty
|
|
{
|
|
public string Title { get; set; }
|
|
public IList<string> Categories { get; private set; }
|
|
|
|
public NonDefaultConstructorWithReadOnlyCollectionProperty(string title)
|
|
{
|
|
Title = title;
|
|
Categories = new List<string>();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void NonDefaultConstructorWithReadOnlyCollectionPropertyTest()
|
|
{
|
|
NonDefaultConstructorWithReadOnlyCollectionProperty c1 = new NonDefaultConstructorWithReadOnlyCollectionProperty("blah");
|
|
c1.Categories.Add("one");
|
|
c1.Categories.Add("two");
|
|
|
|
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""Title"": ""blah"",
|
|
""Categories"": [
|
|
""one"",
|
|
""two""
|
|
]
|
|
}", json);
|
|
|
|
NonDefaultConstructorWithReadOnlyCollectionProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyCollectionProperty>(json);
|
|
Assert.AreEqual(c1.Title, c2.Title);
|
|
Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
|
|
Assert.AreEqual("one", c2.Categories[0]);
|
|
Assert.AreEqual("two", c2.Categories[1]);
|
|
}
|
|
|
|
public class NonDefaultConstructorWithReadOnlyDictionaryProperty
|
|
{
|
|
public string Title { get; set; }
|
|
public IDictionary<string, int> Categories { get; private set; }
|
|
|
|
public NonDefaultConstructorWithReadOnlyDictionaryProperty(string title)
|
|
{
|
|
Title = title;
|
|
Categories = new Dictionary<string, int>();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void NonDefaultConstructorWithReadOnlyDictionaryPropertyTest()
|
|
{
|
|
NonDefaultConstructorWithReadOnlyDictionaryProperty c1 = new NonDefaultConstructorWithReadOnlyDictionaryProperty("blah");
|
|
c1.Categories.Add("one", 1);
|
|
c1.Categories.Add("two", 2);
|
|
|
|
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""Title"": ""blah"",
|
|
""Categories"": {
|
|
""one"": 1,
|
|
""two"": 2
|
|
}
|
|
}", json);
|
|
|
|
NonDefaultConstructorWithReadOnlyDictionaryProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyDictionaryProperty>(json);
|
|
Assert.AreEqual(c1.Title, c2.Title);
|
|
Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
|
|
Assert.AreEqual(1, c2.Categories["one"]);
|
|
Assert.AreEqual(2, c2.Categories["two"]);
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class ClassAttributeBase
|
|
{
|
|
[JsonProperty]
|
|
public string BaseClassValue { get; set; }
|
|
}
|
|
|
|
public class ClassAttributeDerived : ClassAttributeBase
|
|
{
|
|
[JsonProperty]
|
|
public string DerivedClassValue { get; set; }
|
|
|
|
public string NonSerialized { get; set; }
|
|
}
|
|
|
|
public class CollectionClassAttributeDerived : ClassAttributeBase, ICollection<object>
|
|
{
|
|
[JsonProperty]
|
|
public string CollectionDerivedClassValue { get; set; }
|
|
|
|
public void Add(object item)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public bool Contains(object item)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void CopyTo(object[] array, int arrayIndex)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get { throw new NotImplementedException(); }
|
|
}
|
|
|
|
public bool IsReadOnly
|
|
{
|
|
get { throw new NotImplementedException(); }
|
|
}
|
|
|
|
public bool Remove(object item)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public IEnumerator<object> GetEnumerator()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ClassAttributesInheritance()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new ClassAttributeDerived
|
|
{
|
|
BaseClassValue = "BaseClassValue!",
|
|
DerivedClassValue = "DerivedClassValue!",
|
|
NonSerialized = "NonSerialized!"
|
|
}, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""DerivedClassValue"": ""DerivedClassValue!"",
|
|
""BaseClassValue"": ""BaseClassValue!""
|
|
}", json);
|
|
|
|
json = JsonConvert.SerializeObject(new CollectionClassAttributeDerived
|
|
{
|
|
BaseClassValue = "BaseClassValue!",
|
|
CollectionDerivedClassValue = "CollectionDerivedClassValue!"
|
|
}, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""CollectionDerivedClassValue"": ""CollectionDerivedClassValue!"",
|
|
""BaseClassValue"": ""BaseClassValue!""
|
|
}", json);
|
|
}
|
|
|
|
public class PrivateMembersClassWithAttributes
|
|
{
|
|
public PrivateMembersClassWithAttributes(string privateString, string internalString, string readonlyString)
|
|
{
|
|
_privateString = privateString;
|
|
_readonlyString = readonlyString;
|
|
_internalString = internalString;
|
|
}
|
|
|
|
public PrivateMembersClassWithAttributes()
|
|
{
|
|
_readonlyString = "default!";
|
|
}
|
|
|
|
[JsonProperty] private string _privateString;
|
|
[JsonProperty] private readonly string _readonlyString;
|
|
[JsonProperty] internal string _internalString;
|
|
|
|
public string UseValue()
|
|
{
|
|
return _readonlyString;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void PrivateMembersClassWithAttributesTest()
|
|
{
|
|
PrivateMembersClassWithAttributes c1 = new PrivateMembersClassWithAttributes("privateString!", "internalString!", "readonlyString!");
|
|
|
|
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
|
Assert.AreEqual(@"{
|
|
""_privateString"": ""privateString!"",
|
|
""_readonlyString"": ""readonlyString!"",
|
|
""_internalString"": ""internalString!""
|
|
}", json);
|
|
|
|
PrivateMembersClassWithAttributes c2 = JsonConvert.DeserializeObject<PrivateMembersClassWithAttributes>(json);
|
|
Assert.AreEqual("readonlyString!", c2.UseValue());
|
|
}
|
|
|
|
public partial class BusRun
|
|
{
|
|
public IEnumerable<Nullable<DateTime>> Departures { get; set; }
|
|
public Boolean WheelchairAccessible { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeGenericEnumerableProperty()
|
|
{
|
|
BusRun r = JsonConvert.DeserializeObject<BusRun>("{\"Departures\":[\"\\/Date(1309874148734-0400)\\/\",\"\\/Date(1309874148739-0400)\\/\",null],\"WheelchairAccessible\":true}");
|
|
|
|
Assert.AreEqual(3, r.Departures.Count());
|
|
Assert.IsNotNull(r.Departures.ElementAt(0));
|
|
Assert.IsNotNull(r.Departures.ElementAt(1));
|
|
Assert.IsNull(r.Departures.ElementAt(2));
|
|
}
|
|
|
|
#if !(NET20)
|
|
[DataContract]
|
|
public class BaseType
|
|
{
|
|
|
|
[DataMember] public string zebra;
|
|
}
|
|
|
|
[DataContract]
|
|
public class DerivedType : BaseType
|
|
{
|
|
[DataMember(Order = 0)] public string bird;
|
|
[DataMember(Order = 1)] public string parrot;
|
|
[DataMember] public string dog;
|
|
[DataMember(Order = 3)] public string antelope;
|
|
[DataMember] public string cat;
|
|
[JsonProperty(Order = 1)] public string albatross;
|
|
[JsonProperty(Order = -2)] public string dinosaur;
|
|
}
|
|
|
|
[Test]
|
|
public void JsonPropertyDataMemberOrder()
|
|
{
|
|
DerivedType d = new DerivedType();
|
|
string json = JsonConvert.SerializeObject(d, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""dinosaur"": null,
|
|
""dog"": null,
|
|
""cat"": null,
|
|
""zebra"": null,
|
|
""bird"": null,
|
|
""parrot"": null,
|
|
""albatross"": null,
|
|
""antelope"": null
|
|
}", json);
|
|
}
|
|
#endif
|
|
|
|
public class ClassWithException
|
|
{
|
|
public IList<Exception> Exceptions { get; set; }
|
|
|
|
public ClassWithException()
|
|
{
|
|
Exceptions = new List<Exception>();
|
|
}
|
|
}
|
|
|
|
#if !(SILVERLIGHT || WINDOWS_PHONE)
|
|
[Test]
|
|
public void SerializeException1()
|
|
{
|
|
ClassWithException classWithException = new ClassWithException();
|
|
try
|
|
{
|
|
throw new Exception("Test Exception");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
classWithException.Exceptions.Add(ex);
|
|
}
|
|
string sex = JsonConvert.SerializeObject(classWithException);
|
|
ClassWithException dex = JsonConvert.DeserializeObject<ClassWithException>(sex);
|
|
Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString());
|
|
|
|
sex = JsonConvert.SerializeObject(classWithException, Formatting.Indented);
|
|
|
|
dex = JsonConvert.DeserializeObject<ClassWithException>(sex); // this fails!
|
|
Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString());
|
|
}
|
|
#endif
|
|
|
|
public void DeserializeIDictionary()
|
|
{
|
|
IDictionary dictionary = JsonConvert.DeserializeObject<IDictionary>("{'name':'value!'}");
|
|
Assert.AreEqual(1, dictionary.Count);
|
|
Assert.AreEqual("value!", dictionary["name"]);
|
|
}
|
|
|
|
public void DeserializeIList()
|
|
{
|
|
IList list = JsonConvert.DeserializeObject<IList>("['1', 'two', 'III']");
|
|
Assert.AreEqual(3, list.Count);
|
|
}
|
|
|
|
public void UriGuidTimeSpanTestClassEmptyTest()
|
|
{
|
|
UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass();
|
|
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Guid"": ""00000000-0000-0000-0000-000000000000"",
|
|
""NullableGuid"": null,
|
|
""TimeSpan"": ""00:00:00"",
|
|
""NullableTimeSpan"": null,
|
|
""Uri"": null
|
|
}", json);
|
|
|
|
UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject<UriGuidTimeSpanTestClass>(json);
|
|
Assert.AreEqual(c1.Guid, c2.Guid);
|
|
Assert.AreEqual(c1.NullableGuid, c2.NullableGuid);
|
|
Assert.AreEqual(c1.TimeSpan, c2.TimeSpan);
|
|
Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
|
|
Assert.AreEqual(c1.Uri, c2.Uri);
|
|
}
|
|
|
|
public void UriGuidTimeSpanTestClassValuesTest()
|
|
{
|
|
UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass
|
|
{
|
|
Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"),
|
|
NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"),
|
|
TimeSpan = TimeSpan.FromDays(1),
|
|
NullableTimeSpan = TimeSpan.FromHours(1),
|
|
Uri = new Uri("http://testuri.com")
|
|
};
|
|
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Guid"": ""1924129c-f7e0-40f3-9607-9939c531395a"",
|
|
""NullableGuid"": ""9e9f3adf-e017-4f72-91e0-617ebe85967d"",
|
|
""TimeSpan"": ""1.00:00:00"",
|
|
""NullableTimeSpan"": ""01:00:00"",
|
|
""Uri"": ""http://testuri.com/""
|
|
}", json);
|
|
|
|
UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject<UriGuidTimeSpanTestClass>(json);
|
|
Assert.AreEqual(c1.Guid, c2.Guid);
|
|
Assert.AreEqual(c1.NullableGuid, c2.NullableGuid);
|
|
Assert.AreEqual(c1.TimeSpan, c2.TimeSpan);
|
|
Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
|
|
Assert.AreEqual(c1.Uri, c2.Uri);
|
|
}
|
|
|
|
[Test]
|
|
public void NullableValueGenericDictionary()
|
|
{
|
|
IDictionary<string, int?> v1 = new Dictionary<string, int?>
|
|
{
|
|
{"First", 1},
|
|
{"Second", null},
|
|
{"Third", 3}
|
|
};
|
|
|
|
string json = JsonConvert.SerializeObject(v1, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""First"": 1,
|
|
""Second"": null,
|
|
""Third"": 3
|
|
}", json);
|
|
|
|
IDictionary<string, int?> v2 = JsonConvert.DeserializeObject<IDictionary<string, int?>>(json);
|
|
Assert.AreEqual(3, v2.Count);
|
|
Assert.AreEqual(1, v2["First"]);
|
|
Assert.AreEqual(null, v2["Second"]);
|
|
Assert.AreEqual(3, v2["Third"]);
|
|
}
|
|
|
|
[Test]
|
|
public void UsingJsonTextWriter()
|
|
{
|
|
// The property of the object has to be a number for the cast exception to occure
|
|
object o = new {p = 1};
|
|
|
|
var json = JObject.FromObject(o);
|
|
|
|
using (var sw = new StringWriter())
|
|
using (var jw = new JsonTextWriter(sw))
|
|
{
|
|
jw.WriteToken(json.CreateReader());
|
|
jw.Flush();
|
|
|
|
string result = sw.ToString();
|
|
Assert.AreEqual(@"{""p"":1}", result);
|
|
}
|
|
}
|
|
|
|
#if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE)
|
|
[Test]
|
|
public void DeserializeConcurrentDictionary()
|
|
{
|
|
IDictionary<string, Component> components = new Dictionary<string, Component>
|
|
{
|
|
{"Key!", new Component()}
|
|
};
|
|
GameObject go = new GameObject
|
|
{
|
|
Components = new ConcurrentDictionary<string, Component>(components),
|
|
Id = "Id!",
|
|
Name = "Name!"
|
|
};
|
|
|
|
string originalJson = JsonConvert.SerializeObject(go, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""Components"": {
|
|
""Key!"": {}
|
|
},
|
|
""Id"": ""Id!"",
|
|
""Name"": ""Name!""
|
|
}", originalJson);
|
|
|
|
GameObject newObject = JsonConvert.DeserializeObject<GameObject>(originalJson);
|
|
|
|
Assert.AreEqual(1, newObject.Components.Count);
|
|
Assert.AreEqual("Id!", newObject.Id);
|
|
Assert.AreEqual("Name!", newObject.Name);
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void DeserializeKeyValuePairArray()
|
|
{
|
|
string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]";
|
|
|
|
IList<KeyValuePair<string, IList<string>>> values = JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>>>(json);
|
|
|
|
Assert.AreEqual(2, values.Count);
|
|
Assert.AreEqual("aaa", values[0].Key);
|
|
Assert.AreEqual(2, values[0].Value.Count);
|
|
Assert.AreEqual("1", values[0].Value[0]);
|
|
Assert.AreEqual("2", values[0].Value[1]);
|
|
Assert.AreEqual("bbb", values[1].Key);
|
|
Assert.AreEqual(2, values[1].Value.Count);
|
|
Assert.AreEqual("3", values[1].Value[0]);
|
|
Assert.AreEqual("4", values[1].Value[1]);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullableKeyValuePairArray()
|
|
{
|
|
string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, null, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]";
|
|
|
|
IList<KeyValuePair<string, IList<string>>?> values = JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>?>>(json);
|
|
|
|
Assert.AreEqual(3, values.Count);
|
|
Assert.AreEqual("aaa", values[0].Value.Key);
|
|
Assert.AreEqual(2, values[0].Value.Value.Count);
|
|
Assert.AreEqual("1", values[0].Value.Value[0]);
|
|
Assert.AreEqual("2", values[0].Value.Value[1]);
|
|
Assert.AreEqual(null, values[1]);
|
|
Assert.AreEqual("bbb", values[2].Value.Key);
|
|
Assert.AreEqual(2, values[2].Value.Value.Count);
|
|
Assert.AreEqual("3", values[2].Value.Value[0]);
|
|
Assert.AreEqual("4", values[2].Value.Value[1]);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (Exception), ExpectedMessage = "Could not deserialize Null to KeyValuePair.")]
|
|
public void DeserializeNullToNonNullableKeyValuePairArray()
|
|
{
|
|
string json = @"[ null ]";
|
|
|
|
JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>>>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeUriWithQuotes()
|
|
{
|
|
string input = "http://test.com/%22foo+bar%22";
|
|
Uri uri = new Uri(input);
|
|
string json = JsonConvert.SerializeObject(uri);
|
|
Uri output = JsonConvert.DeserializeObject<Uri>(json);
|
|
|
|
Assert.AreEqual(uri, output);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeUriWithSlashes()
|
|
{
|
|
string input = @"http://tes/?a=b\\c&d=e\";
|
|
Uri uri = new Uri(input);
|
|
string json = JsonConvert.SerializeObject(uri);
|
|
Uri output = JsonConvert.DeserializeObject<Uri>(json);
|
|
|
|
Assert.AreEqual(uri, output);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeByteArrayWithTypeNameHandling()
|
|
{
|
|
TestObject test = new TestObject("Test", new byte[] {72, 63, 62, 71, 92, 55});
|
|
|
|
JsonSerializer serializer = new JsonSerializer();
|
|
serializer.TypeNameHandling = TypeNameHandling.All;
|
|
|
|
byte[] objectBytes;
|
|
using (MemoryStream bsonStream = new MemoryStream())
|
|
using (JsonWriter bsonWriter = new JsonTextWriter(new StreamWriter(bsonStream)))
|
|
{
|
|
serializer.Serialize(bsonWriter, test);
|
|
bsonWriter.Flush();
|
|
|
|
objectBytes = bsonStream.ToArray();
|
|
}
|
|
|
|
using (MemoryStream bsonStream = new MemoryStream(objectBytes))
|
|
using (JsonReader bsonReader = new JsonTextReader(new StreamReader(bsonStream)))
|
|
{
|
|
// Get exception here
|
|
TestObject newObject = (TestObject) serializer.Deserialize(bsonReader);
|
|
|
|
Assert.AreEqual("Test", newObject.Name);
|
|
Assert.AreEqual(new byte[] {72, 63, 62, 71, 92, 55}, newObject.Data);
|
|
}
|
|
}
|
|
|
|
#if !(SILVERLIGHT || WINDOWS_PHONE || NET20)
|
|
[Test]
|
|
public void DeserializeDecimalsWithCulture()
|
|
{
|
|
CultureInfo initialCulture = Thread.CurrentThread.CurrentCulture;
|
|
|
|
try
|
|
{
|
|
CultureInfo testCulture = CultureInfo.CreateSpecificCulture("nb-NO");
|
|
|
|
Thread.CurrentThread.CurrentCulture = testCulture;
|
|
Thread.CurrentThread.CurrentUICulture = testCulture;
|
|
|
|
string json = @"{ 'Quantity': '1.5', 'OptionalQuantity': '2.2' }";
|
|
|
|
DecimalTestClass c = JsonConvert.DeserializeObject<DecimalTestClass>(json);
|
|
|
|
Assert.AreEqual(1.5m, c.Quantity);
|
|
Assert.AreEqual(2.2d, c.OptionalQuantity);
|
|
}
|
|
finally
|
|
{
|
|
Thread.CurrentThread.CurrentCulture = initialCulture;
|
|
Thread.CurrentThread.CurrentUICulture = initialCulture;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void ReadForTypeHackFixDecimal()
|
|
{
|
|
IList<decimal> d1 = new List<decimal> {1.1m};
|
|
|
|
string json = JsonConvert.SerializeObject(d1);
|
|
|
|
IList<decimal> d2 = JsonConvert.DeserializeObject<IList<decimal>>(json);
|
|
|
|
Assert.AreEqual(d1.Count, d2.Count);
|
|
Assert.AreEqual(d1[0], d2[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void ReadForTypeHackFixDateTimeOffset()
|
|
{
|
|
IList<DateTimeOffset?> d1 = new List<DateTimeOffset?> {null};
|
|
|
|
string json = JsonConvert.SerializeObject(d1);
|
|
|
|
IList<DateTimeOffset?> d2 = JsonConvert.DeserializeObject<IList<DateTimeOffset?>>(json);
|
|
|
|
Assert.AreEqual(d1.Count, d2.Count);
|
|
Assert.AreEqual(d1[0], d2[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void ReadForTypeHackFixByteArray()
|
|
{
|
|
IList<byte[]> d1 = new List<byte[]> {null};
|
|
|
|
string json = JsonConvert.SerializeObject(d1);
|
|
|
|
IList<byte[]> d2 = JsonConvert.DeserializeObject<IList<byte[]>>(json);
|
|
|
|
Assert.AreEqual(d1.Count, d2.Count);
|
|
Assert.AreEqual(d1[0], d2[0]);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeInheritanceHierarchyWithDuplicateProperty()
|
|
{
|
|
Bb b = new Bb();
|
|
b.no = true;
|
|
Aa a = b;
|
|
a.no = int.MaxValue;
|
|
|
|
string json = JsonConvert.SerializeObject(b);
|
|
|
|
Assert.AreEqual(@"{""no"":true}", json);
|
|
|
|
Bb b2 = JsonConvert.DeserializeObject<Bb>(json);
|
|
|
|
Assert.AreEqual(true, b2.no);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Error converting value {null} to type 'System.Int32'. Line 5, position 7.")]
|
|
public void DeserializeNullInt()
|
|
{
|
|
string json = @"[
|
|
1,
|
|
2,
|
|
3,
|
|
null
|
|
]";
|
|
|
|
List<int> numbers = JsonConvert.DeserializeObject<List<int>>(json);
|
|
// JsonSerializationException : Error converting value {null} to type 'System.Int32'. Line 5, position 7.
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeNullableWidgetStruct()
|
|
{
|
|
Widget widget = new Widget {Id = new WidgetId {Value = "id"}};
|
|
|
|
string json = JsonConvert.SerializeObject(widget);
|
|
|
|
Assert.AreEqual(@"{""Id"":{""Value"":""id""}}", json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullableWidgetStruct()
|
|
{
|
|
string json = @"{""Id"":{""Value"":""id""}}";
|
|
|
|
Widget w = JsonConvert.DeserializeObject<Widget>(json);
|
|
|
|
Assert.AreEqual(new WidgetId {Value = "id"}, w.Id);
|
|
Assert.AreEqual(new WidgetId {Value = "id"}, w.Id.Value);
|
|
Assert.AreEqual("id", w.Id.Value.Value);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonReaderException), ExpectedMessage = "Unexpected token when reading integer: Boolean. Line 2, position 22.")]
|
|
public void DeserializeBoolInt()
|
|
{
|
|
string json = @"{
|
|
""PreProperty"": true,
|
|
""PostProperty"": ""-1""
|
|
}";
|
|
|
|
JsonConvert.DeserializeObject<TestObjects.MyClass>(json);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "Unexpected end when setting PreProperty's value. Line 2, position 18.")]
|
|
public void DeserializeUnexpectedEndInt()
|
|
{
|
|
string json = @"{
|
|
""PreProperty"": ";
|
|
|
|
JsonConvert.DeserializeObject<TestObjects.MyClass>(json);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullableGuid()
|
|
{
|
|
string json = @"{""Id"":null}";
|
|
var c = JsonConvert.DeserializeObject<NullableGuid>(json);
|
|
|
|
Assert.AreEqual(null, c.Id);
|
|
|
|
json = @"{""Id"":""d8220a4b-75b1-4b7a-8112-b7bdae956a45""}";
|
|
c = JsonConvert.DeserializeObject<NullableGuid>(json);
|
|
|
|
Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), c.Id);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeGuid()
|
|
{
|
|
Item expected = new Item()
|
|
{
|
|
SourceTypeID = new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"),
|
|
BrokerID = new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"),
|
|
Latitude = 33.657145,
|
|
Longitude = -117.766684,
|
|
TimeStamp = new DateTime(2000, 3, 1, 23, 59, 59, DateTimeKind.Utc),
|
|
Payload = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
|
};
|
|
|
|
string jsonString = JsonConvert.SerializeObject(expected, Formatting.Indented);
|
|
|
|
Assert.AreEqual(@"{
|
|
""SourceTypeID"": ""d8220a4b-75b1-4b7a-8112-b7bdae956a45"",
|
|
""BrokerID"": ""951663c4-924e-4c86-a57a-7ed737501dbd"",
|
|
""Latitude"": 33.657145,
|
|
""Longitude"": -117.766684,
|
|
""TimeStamp"": ""\/Date(951955199000)\/"",
|
|
""Payload"": {
|
|
""$type"": ""System.Byte[], mscorlib"",
|
|
""$value"": ""AAECAwQFBgcICQ==""
|
|
}
|
|
}", jsonString);
|
|
|
|
Item actual = JsonConvert.DeserializeObject<Item>(jsonString);
|
|
|
|
Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), actual.SourceTypeID);
|
|
Assert.AreEqual(new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"), actual.BrokerID);
|
|
Assert.AreEqual(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, actual.Payload);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeObjectDictionary()
|
|
{
|
|
var serializer = JsonSerializer.Create(new JsonSerializerSettings());
|
|
var dict = serializer.Deserialize<Dictionary<string, string>>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}")));
|
|
|
|
Assert.AreEqual("", dict["k1"]);
|
|
Assert.AreEqual("v2", dict["k2"]);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeNullableEnum()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new WithEnums
|
|
{
|
|
Id = 7,
|
|
NullableEnum = null
|
|
});
|
|
|
|
Assert.AreEqual(@"{""Id"":7,""NullableEnum"":null}", json);
|
|
|
|
WithEnums e = JsonConvert.DeserializeObject<WithEnums>(json);
|
|
|
|
Assert.AreEqual(null, e.NullableEnum);
|
|
|
|
json = JsonConvert.SerializeObject(new WithEnums
|
|
{
|
|
Id = 7,
|
|
NullableEnum = MyEnum.Value2
|
|
});
|
|
|
|
Assert.AreEqual(@"{""Id"":7,""NullableEnum"":1}", json);
|
|
|
|
e = JsonConvert.DeserializeObject<WithEnums>(json);
|
|
|
|
Assert.AreEqual(MyEnum.Value2, e.NullableEnum);
|
|
}
|
|
|
|
[Test]
|
|
public void NullableStructWithConverter()
|
|
{
|
|
string json = JsonConvert.SerializeObject(new Widget1 {Id = new WidgetId1 {Value = 1234}});
|
|
|
|
Assert.AreEqual(@"{""Id"":""1234""}", json);
|
|
|
|
Widget1 w = JsonConvert.DeserializeObject<Widget1>(@"{""Id"":""1234""}");
|
|
|
|
Assert.AreEqual(new WidgetId1 {Value = 1234}, w.Id);
|
|
}
|
|
|
|
[Test]
|
|
public void SerializeDictionaryStringStringAndStringObject()
|
|
{
|
|
var serializer = JsonSerializer.Create(new JsonSerializerSettings());
|
|
var dict = serializer.Deserialize<Dictionary<string, string>>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}")));
|
|
|
|
var reader = new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}"));
|
|
var dict2 = serializer.Deserialize<Dictionary<string, object>>(reader);
|
|
|
|
Assert.AreEqual(dict["k1"], dict2["k1"]);
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeEmptyStrings()
|
|
{
|
|
object v = JsonConvert.DeserializeObject<double?>("");
|
|
Assert.IsNull(v);
|
|
|
|
v = JsonConvert.DeserializeObject<char?>("");
|
|
Assert.IsNull(v);
|
|
|
|
v = JsonConvert.DeserializeObject<int?>("");
|
|
Assert.IsNull(v);
|
|
|
|
v = JsonConvert.DeserializeObject<decimal?>("");
|
|
Assert.IsNull(v);
|
|
|
|
v = JsonConvert.DeserializeObject<DateTime?>("");
|
|
Assert.IsNull(v);
|
|
|
|
v = JsonConvert.DeserializeObject<DateTimeOffset?>("");
|
|
Assert.IsNull(v);
|
|
|
|
v = JsonConvert.DeserializeObject<byte[]>("");
|
|
Assert.IsNull(v);
|
|
}
|
|
|
|
public class Sdfsdf
|
|
{
|
|
public double Id { get; set; }
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.Double' is not nullable.")]
|
|
public void DeserializeDoubleFromEmptyString()
|
|
{
|
|
JsonConvert.DeserializeObject<double>("");
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.StringComparison' is not nullable.")]
|
|
public void DeserializeEnumFromEmptyString()
|
|
{
|
|
JsonConvert.DeserializeObject<StringComparison>("");
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (JsonSerializationException), ExpectedMessage = "No JSON content found and type 'System.Int32' is not nullable.")]
|
|
public void DeserializeInt32FromEmptyString()
|
|
{
|
|
JsonConvert.DeserializeObject<int>("");
|
|
}
|
|
|
|
[Test]
|
|
public void DeserializeByteArrayFromEmptyString()
|
|
{
|
|
byte[] b = JsonConvert.DeserializeObject<byte[]>("");
|
|
Assert.IsNull(b);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (ArgumentNullException), ExpectedMessage = @"Value cannot be null.
|
|
Parameter name: value")]
|
|
public void DeserializeDoubleFromNullString()
|
|
{
|
|
JsonConvert.DeserializeObject<double>(null);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException(typeof (ArgumentNullException), ExpectedMessage = @"Value cannot be null.
|
|
Parameter name: value")]
|
|
public void DeserializeFromNullString()
|
|
{
|
|
JsonConvert.DeserializeObject(null);
|
|
}
|
|
}
|
|
|
|
public class Widget1
|
|
{
|
|
public WidgetId1? Id { get; set; }
|
|
}
|
|
|
|
[JsonConverter(typeof(WidgetIdJsonConverter))]
|
|
public struct WidgetId1
|
|
{
|
|
public long Value { get; set; }
|
|
}
|
|
|
|
public class WidgetIdJsonConverter : JsonConverter
|
|
{
|
|
public override bool CanConvert(Type objectType)
|
|
{
|
|
return objectType == typeof(WidgetId1) || objectType == typeof(WidgetId1?);
|
|
}
|
|
|
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
|
{
|
|
WidgetId1 id = (WidgetId1)value;
|
|
writer.WriteValue(id.Value.ToString());
|
|
}
|
|
|
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
|
{
|
|
if (reader.TokenType == JsonToken.Null)
|
|
return null;
|
|
return new WidgetId1 { Value = int.Parse(reader.Value.ToString()) };
|
|
}
|
|
}
|
|
|
|
|
|
public enum MyEnum
|
|
{
|
|
Value1,
|
|
Value2,
|
|
Value3
|
|
}
|
|
|
|
public class WithEnums
|
|
{
|
|
public int Id { get; set; }
|
|
public MyEnum? NullableEnum { get; set; }
|
|
}
|
|
|
|
public class Item
|
|
{
|
|
public Guid SourceTypeID { get; set; }
|
|
public Guid BrokerID { get; set; }
|
|
public double Latitude { get; set; }
|
|
public double Longitude { get; set; }
|
|
public DateTime TimeStamp { get; set; }
|
|
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
|
|
public object Payload { get; set; }
|
|
}
|
|
|
|
public class NullableGuid
|
|
{
|
|
public Guid? Id { get; set; }
|
|
}
|
|
|
|
public class Widget
|
|
{
|
|
public WidgetId? Id { get; set; }
|
|
}
|
|
|
|
public struct WidgetId
|
|
{
|
|
public string Value { get; set; }
|
|
}
|
|
|
|
public class DecimalTestClass
|
|
{
|
|
public decimal Quantity { get; set; }
|
|
public double OptionalQuantity { get; set; }
|
|
}
|
|
|
|
public class TestObject
|
|
{
|
|
public TestObject()
|
|
{
|
|
|
|
}
|
|
|
|
public TestObject(string name, byte[] data)
|
|
{
|
|
Name = name;
|
|
Data = data;
|
|
}
|
|
|
|
public string Name { get; set; }
|
|
public byte[] Data { get; set; }
|
|
}
|
|
|
|
public class UriGuidTimeSpanTestClass
|
|
{
|
|
public Guid Guid { get; set; }
|
|
public Guid? NullableGuid { get; set; }
|
|
public TimeSpan TimeSpan { get; set; }
|
|
public TimeSpan? NullableTimeSpan { get; set; }
|
|
public Uri Uri { get; set; }
|
|
}
|
|
|
|
internal class Aa
|
|
{
|
|
public int no;
|
|
}
|
|
|
|
internal class Bb : Aa
|
|
{
|
|
public bool no;
|
|
}
|
|
|
|
#if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE)
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class GameObject
|
|
{
|
|
[JsonProperty]
|
|
public string Id { get; set; }
|
|
|
|
[JsonProperty]
|
|
public string Name { get; set; }
|
|
|
|
[JsonProperty] public ConcurrentDictionary<string, Component> Components;
|
|
|
|
public GameObject()
|
|
{
|
|
Components = new ConcurrentDictionary<string, Component>();
|
|
}
|
|
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class Component
|
|
{
|
|
[JsonIgnore] // Ignore circular reference
|
|
public GameObject GameObject { get; set; }
|
|
|
|
public Component()
|
|
{
|
|
}
|
|
}
|
|
|
|
[JsonObject(MemberSerialization.OptIn)]
|
|
public class TestComponent : Component
|
|
{
|
|
[JsonProperty]
|
|
public int MyProperty { get; set; }
|
|
|
|
public TestComponent()
|
|
{
|
|
}
|
|
}
|
|
#endif
|
|
} |