PageRenderTime 118ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 2ms

/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs

https://github.com/99strong99/Newtonsoft.Json
C# | 10919 lines | 9618 code | 1115 blank | 186 comment | 90 complexity | 81370c05b63ccbc8000265efea61c55d MD5 | raw file
  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. using System;
  26. using System.ComponentModel;
  27. #if !(NET35 || NET20)
  28. using System.Collections.Concurrent;
  29. #endif
  30. using System.Collections.Generic;
  31. #if !(NET20 || NET35 || PORTABLE)
  32. using System.Numerics;
  33. #endif
  34. #if !NET20 && !NETFX_CORE
  35. using System.ComponentModel.DataAnnotations;
  36. using System.Configuration;
  37. using System.Runtime.CompilerServices;
  38. using System.Runtime.Serialization.Formatters;
  39. using System.Threading;
  40. using System.Web.Script.Serialization;
  41. #endif
  42. using System.Text;
  43. using System.Text.RegularExpressions;
  44. #if !NETFX_CORE
  45. using NUnit.Framework;
  46. #else
  47. using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  48. using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  49. using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  50. #endif
  51. using Newtonsoft.Json;
  52. using System.IO;
  53. using System.Collections;
  54. using System.Xml;
  55. using System.Xml.Serialization;
  56. using System.Collections.ObjectModel;
  57. using Newtonsoft.Json.Bson;
  58. using Newtonsoft.Json.Linq;
  59. using Newtonsoft.Json.Converters;
  60. #if !NET20
  61. using System.Runtime.Serialization.Json;
  62. #endif
  63. using Newtonsoft.Json.Serialization;
  64. using Newtonsoft.Json.Tests.Linq;
  65. using Newtonsoft.Json.Tests.TestObjects;
  66. using System.Runtime.Serialization;
  67. using System.Globalization;
  68. using Newtonsoft.Json.Utilities;
  69. using System.Reflection;
  70. #if !NET20
  71. using System.Xml.Linq;
  72. using System.Collections.Specialized;
  73. using System.Linq.Expressions;
  74. #endif
  75. #if !(NET35 || NET20)
  76. using System.Dynamic;
  77. #endif
  78. #if NET20
  79. using Newtonsoft.Json.Utilities.LinqBridge;
  80. #else
  81. using System.Linq;
  82. #endif
  83. #if !(NETFX_CORE)
  84. using System.Drawing;
  85. using System.Diagnostics;
  86. #endif
  87. namespace Newtonsoft.Json.Tests.Serialization
  88. {
  89. [TestFixture]
  90. public class JsonSerializerTest : TestFixtureBase
  91. {
  92. [Test]
  93. public void ExtensionDataWithNull()
  94. {
  95. string json = @"{
  96. 'TaxRate': 0.125,
  97. 'a':null
  98. }";
  99. var invoice = JsonConvert.DeserializeObject<ExtendedObject>(json);
  100. Assert.AreEqual(JTokenType.Null, invoice._additionalData["a"].Type);
  101. Assert.AreEqual(typeof(double), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType());
  102. string result = JsonConvert.SerializeObject(invoice);
  103. Assert.AreEqual(@"{""TaxRate"":0.125,""a"":null}", result);
  104. }
  105. [Test]
  106. public void ExtensionDataFloatParseHandling()
  107. {
  108. string json = @"{
  109. 'TaxRate': 0.125,
  110. 'a':null
  111. }";
  112. var invoice = JsonConvert.DeserializeObject<ExtendedObject>(json, new JsonSerializerSettings
  113. {
  114. FloatParseHandling = FloatParseHandling.Decimal
  115. });
  116. Assert.AreEqual(typeof(decimal), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType());
  117. }
  118. #pragma warning disable 649
  119. class ExtendedObject
  120. {
  121. [JsonExtensionData]
  122. internal IDictionary<string, JToken> _additionalData;
  123. }
  124. #pragma warning restore 649
  125. public class GenericItem<T>
  126. {
  127. public T Value { get; set; }
  128. }
  129. public class NonGenericItem : GenericItem<string>
  130. {
  131. }
  132. public class GenericClass<T, TValue> : IEnumerable<T>
  133. where T : GenericItem<TValue>, new()
  134. {
  135. public IList<T> Items { get; set; }
  136. public GenericClass()
  137. {
  138. Items = new List<T>();
  139. }
  140. public IEnumerator<T> GetEnumerator()
  141. {
  142. if (Items != null)
  143. {
  144. foreach (T item in Items)
  145. {
  146. yield return item;
  147. }
  148. }
  149. else
  150. yield break;
  151. }
  152. IEnumerator IEnumerable.GetEnumerator()
  153. {
  154. return GetEnumerator();
  155. }
  156. }
  157. public class NonGenericClass : GenericClass<GenericItem<string>, string>
  158. {
  159. }
  160. #pragma warning disable 169
  161. public class CustomerInvoice
  162. {
  163. // we're only modifing the tax rate
  164. public decimal TaxRate { get; set; }
  165. // everything else gets stored here
  166. [JsonExtensionData]
  167. private IDictionary<string, JToken> _additionalData;
  168. }
  169. #pragma warning restore 169
  170. [Test]
  171. public void ExtensionDataExample()
  172. {
  173. string json = @"{
  174. 'HourlyRate': 150,
  175. 'Hours': 40,
  176. 'TaxRate': 0.125
  177. }";
  178. var invoice = JsonConvert.DeserializeObject<CustomerInvoice>(json);
  179. // increase tax to 15%
  180. invoice.TaxRate = 0.15m;
  181. string result = JsonConvert.SerializeObject(invoice);
  182. // {
  183. // 'TaxRate': 0.15,
  184. // 'HourlyRate': 150,
  185. // 'Hours': 40
  186. // }
  187. Assert.AreEqual(@"{""TaxRate"":0.15,""HourlyRate"":150,""Hours"":40}", result);
  188. }
  189. public class ExtensionDataTestClass
  190. {
  191. public string Name { get; set; }
  192. [JsonProperty("custom_name")]
  193. public string CustomName { get; set; }
  194. [JsonIgnore]
  195. public IList<int> Ignored { get; set; }
  196. public bool GetPrivate { get; internal set; }
  197. public bool GetOnly
  198. {
  199. get { return true; }
  200. }
  201. public readonly string Readonly = "Readonly";
  202. public IList<int> Ints { get; set; }
  203. [JsonExtensionData]
  204. internal IDictionary<string, JToken> ExtensionData { get; set; }
  205. public ExtensionDataTestClass()
  206. {
  207. Ints = new List<int> { 0 };
  208. }
  209. }
  210. public class JObjectExtensionDataTestClass
  211. {
  212. public string Name { get; set; }
  213. [JsonExtensionData]
  214. public JObject ExtensionData { get; set; }
  215. }
  216. [Test]
  217. public void RoundTripJObjectExtensionData()
  218. {
  219. JObjectExtensionDataTestClass c = new JObjectExtensionDataTestClass();
  220. c.Name = "Name!";
  221. c.ExtensionData = new JObject
  222. {
  223. { "one", 1 },
  224. { "two", "II" },
  225. { "three", new JArray(1, 1, 1) }
  226. };
  227. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  228. JObjectExtensionDataTestClass c2 = JsonConvert.DeserializeObject<JObjectExtensionDataTestClass>(json);
  229. Assert.AreEqual("Name!", c2.Name);
  230. Assert.IsTrue(JToken.DeepEquals(c.ExtensionData, c2.ExtensionData));
  231. }
  232. public class BaseClass
  233. {
  234. internal bool IsTransient { get; set; }
  235. }
  236. public class ChildClass : BaseClass
  237. {
  238. public new bool IsTransient { get; set; }
  239. }
  240. [Test]
  241. public void NewProperty()
  242. {
  243. Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClass { IsTransient = true }));
  244. var childClass = JsonConvert.DeserializeObject<ChildClass>(@"{""IsTransient"":true}");
  245. Assert.AreEqual(true, childClass.IsTransient);
  246. }
  247. public class BaseClassVirtual
  248. {
  249. internal virtual bool IsTransient { get; set; }
  250. }
  251. public class ChildClassVirtual : BaseClassVirtual
  252. {
  253. public virtual new bool IsTransient { get; set; }
  254. }
  255. [Test]
  256. public void NewPropertyVirtual()
  257. {
  258. Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClassVirtual { IsTransient = true }));
  259. var childClass = JsonConvert.DeserializeObject<ChildClassVirtual>(@"{""IsTransient"":true}");
  260. Assert.AreEqual(true, childClass.IsTransient);
  261. }
  262. public class ResponseWithNewGenericProperty<T> : SimpleResponse
  263. {
  264. public new T Data { get; set; }
  265. }
  266. public class ResponseWithNewGenericPropertyVirtual<T> : SimpleResponse
  267. {
  268. public virtual new T Data { get; set; }
  269. }
  270. public class ResponseWithNewGenericPropertyOverride<T> : ResponseWithNewGenericPropertyVirtual<T>
  271. {
  272. public override T Data { get; set; }
  273. }
  274. public abstract class SimpleResponse
  275. {
  276. public string Result { get; set; }
  277. public string Message { get; set; }
  278. public object Data { get; set; }
  279. protected SimpleResponse()
  280. {
  281. }
  282. protected SimpleResponse(string message)
  283. {
  284. Message = message;
  285. }
  286. }
  287. [Test]
  288. public void CanSerializeWithBuiltInTypeAsGenericArgument()
  289. {
  290. var input = new ResponseWithNewGenericProperty<int>()
  291. {
  292. Message = "Trying out integer as type parameter",
  293. Data = 25,
  294. Result = "This should be fine"
  295. };
  296. var json = JsonConvert.SerializeObject(input);
  297. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<int>>(json);
  298. Assert.AreEqual(input.Data, deserialized.Data);
  299. Assert.AreEqual(input.Message, deserialized.Message);
  300. Assert.AreEqual(input.Result, deserialized.Result);
  301. }
  302. [Test]
  303. public void CanSerializeWithBuiltInTypeAsGenericArgumentVirtual()
  304. {
  305. var input = new ResponseWithNewGenericPropertyVirtual<int>()
  306. {
  307. Message = "Trying out integer as type parameter",
  308. Data = 25,
  309. Result = "This should be fine"
  310. };
  311. var json = JsonConvert.SerializeObject(input);
  312. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyVirtual<int>>(json);
  313. Assert.AreEqual(input.Data, deserialized.Data);
  314. Assert.AreEqual(input.Message, deserialized.Message);
  315. Assert.AreEqual(input.Result, deserialized.Result);
  316. }
  317. [Test]
  318. public void CanSerializeWithBuiltInTypeAsGenericArgumentOverride()
  319. {
  320. var input = new ResponseWithNewGenericPropertyOverride<int>()
  321. {
  322. Message = "Trying out integer as type parameter",
  323. Data = 25,
  324. Result = "This should be fine"
  325. };
  326. var json = JsonConvert.SerializeObject(input);
  327. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyOverride<int>>(json);
  328. Assert.AreEqual(input.Data, deserialized.Data);
  329. Assert.AreEqual(input.Message, deserialized.Message);
  330. Assert.AreEqual(input.Result, deserialized.Result);
  331. }
  332. [Test]
  333. public void CanSerializedWithGenericClosedTypeAsArgument()
  334. {
  335. var input = new ResponseWithNewGenericProperty<List<int>>()
  336. {
  337. Message = "More complex case - generic list of int",
  338. Data = Enumerable.Range(50, 70).ToList(),
  339. Result = "This should be fine too"
  340. };
  341. var json = JsonConvert.SerializeObject(input);
  342. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<List<int>>>(json);
  343. Assert.AreEqual(input.Data, deserialized.Data);
  344. Assert.AreEqual(input.Message, deserialized.Message);
  345. Assert.AreEqual(input.Result, deserialized.Result);
  346. }
  347. [Test]
  348. public void JsonSerializerProperties()
  349. {
  350. JsonSerializer serializer = new JsonSerializer();
  351. DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
  352. serializer.Binder = customBinder;
  353. Assert.AreEqual(customBinder, serializer.Binder);
  354. serializer.CheckAdditionalContent = true;
  355. Assert.AreEqual(true, serializer.CheckAdditionalContent);
  356. serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
  357. Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializer.ConstructorHandling);
  358. #if !NETFX_CORE
  359. serializer.Context = new StreamingContext(StreamingContextStates.Other);
  360. Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializer.Context);
  361. #endif
  362. CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
  363. serializer.ContractResolver = resolver;
  364. Assert.AreEqual(resolver, serializer.ContractResolver);
  365. serializer.Converters.Add(new StringEnumConverter());
  366. Assert.AreEqual(1, serializer.Converters.Count);
  367. serializer.Culture = new CultureInfo("en-nz");
  368. Assert.AreEqual("en-NZ", serializer.Culture.ToString());
  369. serializer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
  370. Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializer.DateFormatHandling);
  371. serializer.DateFormatString = "yyyy";
  372. Assert.AreEqual("yyyy", serializer.DateFormatString);
  373. serializer.DateParseHandling = DateParseHandling.None;
  374. Assert.AreEqual(DateParseHandling.None, serializer.DateParseHandling);
  375. serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  376. Assert.AreEqual(DateTimeZoneHandling.Utc, serializer.DateTimeZoneHandling);
  377. serializer.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
  378. Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializer.DefaultValueHandling);
  379. serializer.FloatFormatHandling = FloatFormatHandling.Symbol;
  380. Assert.AreEqual(FloatFormatHandling.Symbol, serializer.FloatFormatHandling);
  381. serializer.FloatParseHandling = FloatParseHandling.Decimal;
  382. Assert.AreEqual(FloatParseHandling.Decimal, serializer.FloatParseHandling);
  383. serializer.Formatting = Formatting.Indented;
  384. Assert.AreEqual(Formatting.Indented, serializer.Formatting);
  385. serializer.MaxDepth = 9001;
  386. Assert.AreEqual(9001, serializer.MaxDepth);
  387. serializer.MissingMemberHandling = MissingMemberHandling.Error;
  388. Assert.AreEqual(MissingMemberHandling.Error, serializer.MissingMemberHandling);
  389. serializer.NullValueHandling = NullValueHandling.Ignore;
  390. Assert.AreEqual(NullValueHandling.Ignore, serializer.NullValueHandling);
  391. serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
  392. Assert.AreEqual(ObjectCreationHandling.Replace, serializer.ObjectCreationHandling);
  393. serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
  394. Assert.AreEqual(PreserveReferencesHandling.All, serializer.PreserveReferencesHandling);
  395. serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  396. Assert.AreEqual(ReferenceLoopHandling.Ignore, serializer.ReferenceLoopHandling);
  397. IdReferenceResolver referenceResolver = new IdReferenceResolver();
  398. serializer.ReferenceResolver = referenceResolver;
  399. Assert.AreEqual(referenceResolver, serializer.ReferenceResolver);
  400. serializer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
  401. Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializer.StringEscapeHandling);
  402. MemoryTraceWriter traceWriter = new MemoryTraceWriter();
  403. serializer.TraceWriter = traceWriter;
  404. Assert.AreEqual(traceWriter, serializer.TraceWriter);
  405. #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
  406. serializer.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
  407. Assert.AreEqual(FormatterAssemblyStyle.Full, serializer.TypeNameAssemblyFormat);
  408. #endif
  409. serializer.TypeNameHandling = TypeNameHandling.All;
  410. Assert.AreEqual(TypeNameHandling.All, serializer.TypeNameHandling);
  411. }
  412. [Test]
  413. public void JsonSerializerSettingsProperties()
  414. {
  415. JsonSerializerSettings settings = new JsonSerializerSettings();
  416. DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
  417. settings.Binder = customBinder;
  418. Assert.AreEqual(customBinder, settings.Binder);
  419. settings.CheckAdditionalContent = true;
  420. Assert.AreEqual(true, settings.CheckAdditionalContent);
  421. settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
  422. Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, settings.ConstructorHandling);
  423. #if !NETFX_CORE
  424. settings.Context = new StreamingContext(StreamingContextStates.Other);
  425. Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), settings.Context);
  426. #endif
  427. CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
  428. settings.ContractResolver = resolver;
  429. Assert.AreEqual(resolver, settings.ContractResolver);
  430. settings.Converters.Add(new StringEnumConverter());
  431. Assert.AreEqual(1, settings.Converters.Count);
  432. settings.Culture = new CultureInfo("en-nz");
  433. Assert.AreEqual("en-NZ", settings.Culture.ToString());
  434. settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
  435. Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, settings.DateFormatHandling);
  436. settings.DateFormatString = "yyyy";
  437. Assert.AreEqual("yyyy", settings.DateFormatString);
  438. settings.DateParseHandling = DateParseHandling.None;
  439. Assert.AreEqual(DateParseHandling.None, settings.DateParseHandling);
  440. settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  441. Assert.AreEqual(DateTimeZoneHandling.Utc, settings.DateTimeZoneHandling);
  442. settings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
  443. Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, settings.DefaultValueHandling);
  444. settings.FloatFormatHandling = FloatFormatHandling.Symbol;
  445. Assert.AreEqual(FloatFormatHandling.Symbol, settings.FloatFormatHandling);
  446. settings.FloatParseHandling = FloatParseHandling.Decimal;
  447. Assert.AreEqual(FloatParseHandling.Decimal, settings.FloatParseHandling);
  448. settings.Formatting = Formatting.Indented;
  449. Assert.AreEqual(Formatting.Indented, settings.Formatting);
  450. settings.MaxDepth = 9001;
  451. Assert.AreEqual(9001, settings.MaxDepth);
  452. settings.MissingMemberHandling = MissingMemberHandling.Error;
  453. Assert.AreEqual(MissingMemberHandling.Error, settings.MissingMemberHandling);
  454. settings.NullValueHandling = NullValueHandling.Ignore;
  455. Assert.AreEqual(NullValueHandling.Ignore, settings.NullValueHandling);
  456. settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
  457. Assert.AreEqual(ObjectCreationHandling.Replace, settings.ObjectCreationHandling);
  458. settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
  459. Assert.AreEqual(PreserveReferencesHandling.All, settings.PreserveReferencesHandling);
  460. settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  461. Assert.AreEqual(ReferenceLoopHandling.Ignore, settings.ReferenceLoopHandling);
  462. IdReferenceResolver referenceResolver = new IdReferenceResolver();
  463. settings.ReferenceResolver = referenceResolver;
  464. Assert.AreEqual(referenceResolver, settings.ReferenceResolver);
  465. settings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
  466. Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, settings.StringEscapeHandling);
  467. MemoryTraceWriter traceWriter = new MemoryTraceWriter();
  468. settings.TraceWriter = traceWriter;
  469. Assert.AreEqual(traceWriter, settings.TraceWriter);
  470. #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
  471. settings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
  472. Assert.AreEqual(FormatterAssemblyStyle.Full, settings.TypeNameAssemblyFormat);
  473. #endif
  474. settings.TypeNameHandling = TypeNameHandling.All;
  475. Assert.AreEqual(TypeNameHandling.All, settings.TypeNameHandling);
  476. }
  477. [Test]
  478. public void JsonSerializerProxyProperties()
  479. {
  480. JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer()));
  481. DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
  482. serializerProxy.Binder = customBinder;
  483. Assert.AreEqual(customBinder, serializerProxy.Binder);
  484. serializerProxy.CheckAdditionalContent = true;
  485. Assert.AreEqual(true, serializerProxy.CheckAdditionalContent);
  486. serializerProxy.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
  487. Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializerProxy.ConstructorHandling);
  488. #if !NETFX_CORE
  489. serializerProxy.Context = new StreamingContext(StreamingContextStates.Other);
  490. Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializerProxy.Context);
  491. #endif
  492. CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
  493. serializerProxy.ContractResolver = resolver;
  494. Assert.AreEqual(resolver, serializerProxy.ContractResolver);
  495. serializerProxy.Converters.Add(new StringEnumConverter());
  496. Assert.AreEqual(1, serializerProxy.Converters.Count);
  497. serializerProxy.Culture = new CultureInfo("en-nz");
  498. Assert.AreEqual("en-NZ", serializerProxy.Culture.ToString());
  499. serializerProxy.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
  500. Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializerProxy.DateFormatHandling);
  501. serializerProxy.DateFormatString = "yyyy";
  502. Assert.AreEqual("yyyy", serializerProxy.DateFormatString);
  503. serializerProxy.DateParseHandling = DateParseHandling.None;
  504. Assert.AreEqual(DateParseHandling.None, serializerProxy.DateParseHandling);
  505. serializerProxy.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  506. Assert.AreEqual(DateTimeZoneHandling.Utc, serializerProxy.DateTimeZoneHandling);
  507. serializerProxy.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
  508. Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializerProxy.DefaultValueHandling);
  509. serializerProxy.FloatFormatHandling = FloatFormatHandling.Symbol;
  510. Assert.AreEqual(FloatFormatHandling.Symbol, serializerProxy.FloatFormatHandling);
  511. serializerProxy.FloatParseHandling = FloatParseHandling.Decimal;
  512. Assert.AreEqual(FloatParseHandling.Decimal, serializerProxy.FloatParseHandling);
  513. serializerProxy.Formatting = Formatting.Indented;
  514. Assert.AreEqual(Formatting.Indented, serializerProxy.Formatting);
  515. serializerProxy.MaxDepth = 9001;
  516. Assert.AreEqual(9001, serializerProxy.MaxDepth);
  517. serializerProxy.MissingMemberHandling = MissingMemberHandling.Error;
  518. Assert.AreEqual(MissingMemberHandling.Error, serializerProxy.MissingMemberHandling);
  519. serializerProxy.NullValueHandling = NullValueHandling.Ignore;
  520. Assert.AreEqual(NullValueHandling.Ignore, serializerProxy.NullValueHandling);
  521. serializerProxy.ObjectCreationHandling = ObjectCreationHandling.Replace;
  522. Assert.AreEqual(ObjectCreationHandling.Replace, serializerProxy.ObjectCreationHandling);
  523. serializerProxy.PreserveReferencesHandling = PreserveReferencesHandling.All;
  524. Assert.AreEqual(PreserveReferencesHandling.All, serializerProxy.PreserveReferencesHandling);
  525. serializerProxy.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  526. Assert.AreEqual(ReferenceLoopHandling.Ignore, serializerProxy.ReferenceLoopHandling);
  527. IdReferenceResolver referenceResolver = new IdReferenceResolver();
  528. serializerProxy.ReferenceResolver = referenceResolver;
  529. Assert.AreEqual(referenceResolver, serializerProxy.ReferenceResolver);
  530. serializerProxy.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
  531. Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializerProxy.StringEscapeHandling);
  532. MemoryTraceWriter traceWriter = new MemoryTraceWriter();
  533. serializerProxy.TraceWriter = traceWriter;
  534. Assert.AreEqual(traceWriter, serializerProxy.TraceWriter);
  535. #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
  536. serializerProxy.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
  537. Assert.AreEqual(FormatterAssemblyStyle.Full, serializerProxy.TypeNameAssemblyFormat);
  538. #endif
  539. serializerProxy.TypeNameHandling = TypeNameHandling.All;
  540. Assert.AreEqual(TypeNameHandling.All, serializerProxy.TypeNameHandling);
  541. }
  542. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  543. [Test]
  544. public void DeserializeISerializableIConvertible()
  545. {
  546. Ratio ratio = new Ratio(2, 1);
  547. string json = JsonConvert.SerializeObject(ratio);
  548. Assert.AreEqual(@"{""n"":2,""d"":1}", json);
  549. Ratio ratio2 = JsonConvert.DeserializeObject<Ratio>(json);
  550. Assert.AreEqual(ratio.Denominator, ratio2.Denominator);
  551. Assert.AreEqual(ratio.Numerator, ratio2.Numerator);
  552. }
  553. #endif
  554. [Test]
  555. public void DeserializeLargeFloat()
  556. {
  557. object o = JsonConvert.DeserializeObject("100000000000000000000000000000000000000.0");
  558. CustomAssert.IsInstanceOfType(typeof(double), o);
  559. Assert.IsTrue(MathUtils.ApproxEquals(1E+38, (double)o));
  560. }
  561. [Test]
  562. public void SerializeDeserializeRegex()
  563. {
  564. Regex regex = new Regex("(hi)", RegexOptions.CultureInvariant);
  565. string json = JsonConvert.SerializeObject(regex, Formatting.Indented);
  566. Regex r2 = JsonConvert.DeserializeObject<Regex>(json);
  567. Assert.AreEqual("(hi)", r2.ToString());
  568. Assert.AreEqual(RegexOptions.CultureInvariant, r2.Options);
  569. }
  570. [Test]
  571. public void ExtensionDataTest()
  572. {
  573. string json = @"{
  574. ""Ints"": [1,2,3],
  575. ""Ignored"": [1,2,3],
  576. ""Readonly"": ""Readonly"",
  577. ""Name"": ""Actually set!"",
  578. ""CustomName"": ""Wrong name!"",
  579. ""GetPrivate"": true,
  580. ""GetOnly"": true,
  581. ""NewValueSimple"": true,
  582. ""NewValueComplex"": [1,2,3]
  583. }";
  584. ExtensionDataTestClass c = JsonConvert.DeserializeObject<ExtensionDataTestClass>(json);
  585. Assert.AreEqual("Actually set!", c.Name);
  586. Assert.AreEqual(4, c.Ints.Count);
  587. Assert.AreEqual("Readonly", (string)c.ExtensionData["Readonly"]);
  588. Assert.AreEqual("Wrong name!", (string)c.ExtensionData["CustomName"]);
  589. Assert.AreEqual(true, (bool)c.ExtensionData["GetPrivate"]);
  590. Assert.AreEqual(true, (bool)c.ExtensionData["GetOnly"]);
  591. Assert.AreEqual(true, (bool)c.ExtensionData["NewValueSimple"]);
  592. Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["NewValueComplex"]));
  593. Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["Ignored"]));
  594. Assert.AreEqual(7, c.ExtensionData.Count);
  595. }
  596. public class MultipleExtensionDataAttributesTestClass
  597. {
  598. public string Name { get; set; }
  599. [JsonExtensionData]
  600. internal IDictionary<string, JToken> ExtensionData1 { get; set; }
  601. [JsonExtensionData]
  602. internal IDictionary<string, JToken> ExtensionData2 { get; set; }
  603. }
  604. public class ExtensionDataAttributesInheritanceTestClass : MultipleExtensionDataAttributesTestClass
  605. {
  606. [JsonExtensionData]
  607. internal IDictionary<string, JToken> ExtensionData0 { get; set; }
  608. }
  609. public class FieldExtensionDataAttributeTestClass
  610. {
  611. [JsonExtensionData]
  612. internal IDictionary<object, object> ExtensionData;
  613. }
  614. public class PublicExtensionDataAttributeTestClass
  615. {
  616. public string Name { get; set; }
  617. [JsonExtensionData]
  618. public IDictionary<object, object> ExtensionData;
  619. }
  620. public class PublicExtensionDataAttributeTestClassWithNonDefaultConstructor
  621. {
  622. public string Name { get; set; }
  623. public PublicExtensionDataAttributeTestClassWithNonDefaultConstructor(string name)
  624. {
  625. Name = name;
  626. }
  627. [JsonExtensionData]
  628. public IDictionary<object, object> ExtensionData;
  629. }
  630. public class PublicNoReadExtensionDataAttributeTestClass
  631. {
  632. public string Name { get; set; }
  633. [JsonExtensionData(ReadData = false)]
  634. public IDictionary<object, object> ExtensionData;
  635. }
  636. public class PublicNoWriteExtensionDataAttributeTestClass
  637. {
  638. public string Name { get; set; }
  639. [JsonExtensionData(WriteData = false)]
  640. public IDictionary<object, object> ExtensionData;
  641. }
  642. public class PublicJTokenExtensionDataAttributeTestClass
  643. {
  644. public string Name { get; set; }
  645. [JsonExtensionData]
  646. public IDictionary<string, JToken> ExtensionData;
  647. }
  648. [Test]
  649. public void DeserializeDirectoryAccount()
  650. {
  651. string json = @"{'DisplayName':'John Smith', 'SAMAccountName':'contoso\\johns'}";
  652. DirectoryAccount account = JsonConvert.DeserializeObject<DirectoryAccount>(json);
  653. Assert.AreEqual("John Smith", account.DisplayName);
  654. Assert.AreEqual("contoso", account.Domain);
  655. Assert.AreEqual("johns", account.UserName);
  656. }
  657. [Test]
  658. public void SerializePublicExtensionData()
  659. {
  660. string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass
  661. {
  662. Name = "Name!",
  663. ExtensionData = new Dictionary<object, object>
  664. {
  665. { "Test", 1 }
  666. }
  667. });
  668. Assert.AreEqual(@"{""Name"":""Name!"",""Test"":1}", json);
  669. }
  670. [Test]
  671. public void SerializePublicExtensionDataNull()
  672. {
  673. string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass
  674. {
  675. Name = "Name!"
  676. });
  677. Assert.AreEqual(@"{""Name"":""Name!""}", json);
  678. }
  679. [Test]
  680. public void SerializePublicNoWriteExtensionData()
  681. {
  682. string json = JsonConvert.SerializeObject(new PublicNoWriteExtensionDataAttributeTestClass
  683. {
  684. Name = "Name!",
  685. ExtensionData = new Dictionary<object, object>
  686. {
  687. { "Test", 1 }
  688. }
  689. });
  690. Assert.AreEqual(@"{""Name"":""Name!""}", json);
  691. }
  692. [Test]
  693. public void DeserializeNoReadPublicExtensionData()
  694. {
  695. PublicNoReadExtensionDataAttributeTestClass c = JsonConvert.DeserializeObject<PublicNoReadExtensionDataAttributeTestClass>(@"{""Name"":""Name!"",""Test"":1}");
  696. Assert.AreEqual(null, c.ExtensionData);
  697. }
  698. [Test]
  699. public void SerializePublicExtensionDataCircularReference()
  700. {
  701. var c = new PublicExtensionDataAttributeTestClass
  702. {
  703. Name = "Name!",
  704. ExtensionData = new Dictionary<object, object>
  705. {
  706. { "Test", 1 }
  707. }
  708. };
  709. c.ExtensionData["Self"] = c;
  710. string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings
  711. {
  712. PreserveReferencesHandling = PreserveReferencesHandling.All,
  713. Formatting = Formatting.Indented
  714. });
  715. Assert.AreEqual(@"{
  716. ""$id"": ""1"",
  717. ""Name"": ""Name!"",
  718. ""Test"": 1,
  719. ""Self"": {
  720. ""$ref"": ""1""
  721. }
  722. }", json);
  723. var c2 = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClass>(json, new JsonSerializerSettings
  724. {
  725. PreserveReferencesHandling = PreserveReferencesHandling.All
  726. });
  727. Assert.AreEqual("Name!", c2.Name);
  728. PublicExtensionDataAttributeTestClass bizzaroC2 = (PublicExtensionDataAttributeTestClass)c2.ExtensionData["Self"];
  729. Assert.AreEqual(c2, bizzaroC2);
  730. Assert.AreEqual(1, (long)bizzaroC2.ExtensionData["Test"]);
  731. }
  732. [Test]
  733. public void DeserializePublicJTokenExtensionDataCircularReference()
  734. {
  735. string json = @"{
  736. ""$id"": ""1"",
  737. ""Name"": ""Name!"",
  738. ""Test"": 1,
  739. ""Self"": {
  740. ""$ref"": ""1""
  741. }
  742. }";
  743. var c2 = JsonConvert.DeserializeObject<PublicJTokenExtensionDataAttributeTestClass>(json, new JsonSerializerSettings
  744. {
  745. PreserveReferencesHandling = PreserveReferencesHandling.All
  746. });
  747. Assert.AreEqual("Name!", c2.Name);
  748. JObject bizzaroC2 = (JObject)c2.ExtensionData["Self"];
  749. Assert.AreEqual("Name!", (string)bizzaroC2["Name"]);
  750. Assert.AreEqual(1, (int)bizzaroC2["Test"]);
  751. Assert.AreEqual(1, (int)c2.ExtensionData["Test"]);
  752. }
  753. [Test]
  754. public void DeserializePublicExtensionDataTypeNamdHandling()
  755. {
  756. string json = @"{
  757. ""$id"": ""1"",
  758. ""Name"": ""Name!"",
  759. ""Test"": 1,
  760. ""Self"": {
  761. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"",
  762. ""HourlyWage"": 2.0,
  763. ""Name"": null,
  764. ""BirthDate"": ""0001-01-01T00:00:00"",
  765. ""LastModified"": ""0001-01-01T00:00:00""
  766. }
  767. }";
  768. PublicExtensionDataAttributeTestClass c2 = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClass>(json, new JsonSerializerSettings
  769. {
  770. TypeNameHandling = TypeNameHandling.Objects
  771. });
  772. Assert.AreEqual("Name!", c2.Name);
  773. WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"];
  774. Assert.AreEqual(2m, bizzaroC2.HourlyWage);
  775. }
  776. [Test]
  777. public void DeserializePublicExtensionDataTypeNamdHandlingNonDefaultConstructor()
  778. {
  779. string json = @"{
  780. ""$id"": ""1"",
  781. ""Name"": ""Name!"",
  782. ""Test"": 1,
  783. ""Self"": {
  784. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"",
  785. ""HourlyWage"": 2.0,
  786. ""Name"": null,
  787. ""BirthDate"": ""0001-01-01T00:00:00"",
  788. ""LastModified"": ""0001-01-01T00:00:00""
  789. }
  790. }";
  791. PublicExtensionDataAttributeTestClassWithNonDefaultConstructor c2 = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClassWithNonDefaultConstructor>(json, new JsonSerializerSettings
  792. {
  793. TypeNameHandling = TypeNameHandling.Objects
  794. });
  795. Assert.AreEqual("Name!", c2.Name);
  796. WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"];
  797. Assert.AreEqual(2m, bizzaroC2.HourlyWage);
  798. }
  799. [Test]
  800. public void SerializePublicExtensionDataTypeNamdHandling()
  801. {
  802. PublicExtensionDataAttributeTestClass c = new PublicExtensionDataAttributeTestClass
  803. {
  804. Name = "Name!",
  805. ExtensionData = new Dictionary<object, object>
  806. {
  807. {
  808. "Test", new WagePerson
  809. {
  810. HourlyWage = 2.1m
  811. }
  812. }
  813. }
  814. };
  815. string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings
  816. {
  817. TypeNameHandling = TypeNameHandling.Objects,
  818. Formatting = Formatting.Indented
  819. });
  820. Assert.AreEqual(@"{
  821. ""$type"": ""Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PublicExtensionDataAttributeTestClass, Newtonsoft.Json.Tests"",
  822. ""Name"": ""Name!"",
  823. ""Test"": {
  824. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"",
  825. ""HourlyWage"": 2.1,
  826. ""Name"": null,
  827. ""BirthDate"": ""0001-01-01T00:00:00"",
  828. ""LastModified"": ""0001-01-01T00:00:00""
  829. }
  830. }", json);
  831. }
  832. [Test]
  833. public void DeserializePublicExtensionData()
  834. {
  835. string json = @"{
  836. 'Name':'Name!',
  837. 'NoMatch':'NoMatch!',
  838. 'ExtensionData':{'HAI':true}
  839. }";
  840. var c = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClass>(json);
  841. Assert.AreEqual("Name!", c.Name);
  842. Assert.AreEqual(2, c.ExtensionData.Count);
  843. Assert.AreEqual("NoMatch!", (string)c.ExtensionData["NoMatch"]);
  844. // the ExtensionData property is put into the extension data
  845. // inception
  846. var o = (JObject)c.ExtensionData["ExtensionData"];
  847. Assert.AreEqual(1, o.Count);
  848. Assert.IsTrue(JToken.DeepEquals(new JObject { { "HAI", true } }, o));
  849. }
  850. [Test]
  851. public void FieldExtensionDataAttributeTest_Serialize()
  852. {
  853. FieldExtensionDataAttributeTestClass c = new FieldExtensionDataAttributeTestClass
  854. {
  855. ExtensionData = new Dictionary<object, object>()
  856. };
  857. string json = JsonConvert.SerializeObject(c);
  858. Assert.AreEqual("{}", json);
  859. }
  860. [Test]
  861. public void FieldExtensionDataAttributeTest_Deserialize()
  862. {
  863. var c = JsonConvert.DeserializeObject<FieldExtensionDataAttributeTestClass>("{'first':1,'second':2}");
  864. Assert.AreEqual(2, c.ExtensionData.Count);
  865. Assert.AreEqual(1, (long)c.ExtensionData["first"]);
  866. Assert.AreEqual(2, (long)c.ExtensionData["second"]);
  867. }
  868. [Test]
  869. public void MultipleExtensionDataAttributesTest()
  870. {
  871. var c = JsonConvert.DeserializeObject<MultipleExtensionDataAttributesTestClass>("{'first':[1],'second':[2]}");
  872. Assert.AreEqual(null, c.ExtensionData1);
  873. Assert.AreEqual(2, c.ExtensionData2.Count);
  874. Assert.AreEqual(1, (int)((JArray)c.ExtensionData2["first"])[0]);
  875. Assert.AreEqual(2, (int)((JArray)c.ExtensionData2["second"])[0]);
  876. }
  877. [Test]
  878. public void ExtensionDataAttributesInheritanceTest()
  879. {
  880. var c = JsonConvert.DeserializeObject<ExtensionDataAttributesInheritanceTestClass>("{'first':1,'second':2}");
  881. Assert.AreEqual(null, c.ExtensionData1);
  882. Assert.AreEqual(null, c.ExtensionData2);
  883. Assert.AreEqual(2, c.ExtensionData0.Count);
  884. Assert.AreEqual(1, (int)c.ExtensionData0["first"]);
  885. Assert.AreEqual(2, (int)c.ExtensionData0["second"]);
  886. }
  887. [Test]
  888. public void GenericCollectionInheritance()
  889. {
  890. string json;
  891. GenericClass<GenericItem<string>, string> foo1 = new GenericClass<GenericItem<string>, string>();
  892. foo1.Items.Add(new GenericItem<string> { Value = "Hello" });
  893. json = JsonConvert.SerializeObject(new { selectList = foo1 });
  894. Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json);
  895. GenericClass<NonGenericItem, string> foo2 = new GenericClass<NonGenericItem, string>();
  896. foo2.Items.Add(new NonGenericItem { Value = "Hello" });
  897. json = JsonConvert.SerializeObject(new { selectList = foo2 });
  898. Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json);
  899. NonGenericClass foo3 = new NonGenericClass();
  900. foo3.Items.Add(new NonGenericItem { Value = "Hello" });
  901. json = JsonConvert.SerializeObject(new { selectList = foo3 });
  902. Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json);
  903. }
  904. #if !NET20
  905. [DataContract]
  906. public class BaseDataContractWithHidden
  907. {
  908. [DataMember(Name = "virtualMember")]
  909. public virtual string VirtualMember { get; set; }
  910. [DataMember(Name = "nonVirtualMember")]
  911. public string NonVirtualMember { get; set; }
  912. public virtual object NewMember { get; set; }
  913. }
  914. public class ChildDataContractWithHidden : BaseDataContractWithHidden
  915. {
  916. [DataMember(Name = "NewMember")]
  917. public new virtual string NewMember { get; set; }
  918. public override string VirtualMember { get; set; }
  919. public string AddedMember { get; set; }
  920. }
  921. [Test]
  922. public void ChildDataContractTestWithHidden()
  923. {
  924. var cc = new ChildDataContractWithHidden
  925. {
  926. VirtualMember = "VirtualMember!",
  927. NonVirtualMember = "NonVirtualMember!",
  928. NewMember = "NewMember!"
  929. };
  930. string result = JsonConvert.SerializeObject(cc);
  931. Assert.AreEqual(@"{""NewMember"":""NewMember!"",""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
  932. }
  933. // ignore hiding members compiler warning
  934. #pragma warning disable 108,114
  935. [DataContract]
  936. public class BaseWithContract
  937. {
  938. [DataMember(Name = "VirtualWithDataMemberBase")]
  939. public virtual string VirtualWithDataMember { get; set; }
  940. [DataMember]
  941. public virtual string Virtual { get; set; }
  942. [DataMember(Name = "WithDataMemberBase")]
  943. public string WithDataMember { get; set; }
  944. [DataMember]
  945. public string JustAProperty { get; set; }
  946. }
  947. [DataContract]
  948. public class BaseWithoutContract
  949. {
  950. [DataMember(Name = "VirtualWithDataMemberBase")]
  951. public virtual string VirtualWithDataMember { get; set; }
  952. [DataMember]
  953. public virtual string Virtual { get; set; }
  954. [DataMember(Name = "WithDataMemberBase")]
  955. public string WithDataMember { get; set; }
  956. [DataMember]
  957. public string JustAProperty { get; set; }
  958. }
  959. [DataContract]
  960. public class SubWithoutContractNewProperties : BaseWithContract
  961. {
  962. [DataMember(Name = "VirtualWithDataMemberSub")]
  963. public string VirtualWithDataMember { get; set; }
  964. public string Virtual { get; set; }
  965. [DataMember(Name = "WithDataMemberSub")]
  966. public string WithDataMember { get; set; }
  967. public string JustAProperty { get; set; }
  968. }
  969. [DataContract]
  970. public class SubWithoutContractVirtualProperties : BaseWithContract
  971. {
  972. public override string VirtualWithDataMember { get; set; }
  973. [DataMember(Name = "VirtualSub")]
  974. public override string Virtual { get; set; }
  975. }
  976. [DataContract]
  977. public class SubWithContractNewProperties : BaseWithContract
  978. {
  979. [DataMember(Name = "VirtualWithDataMemberSub")]
  980. public string VirtualWithDataMember { get; set; }
  981. [DataMember(Name = "Virtual2")]
  982. public string Virtual { get; set; }
  983. [DataMember(Name = "WithDataMemberSub")]
  984. public string WithDataMember { get; set; }
  985. [DataMember(Name = "JustAProperty2")]
  986. public string JustAProperty { get; set; }
  987. }
  988. [DataContract]
  989. public class SubWithContractVirtualProperties : BaseWithContract
  990. {
  991. [DataMember(Name = "VirtualWithDataMemberSub")]
  992. public virtual string VirtualWithDataMember { get; set; }
  993. }
  994. #pragma warning restore 108,114
  995. [Test]
  996. public void SubWithoutContractNewPropertiesTest()
  997. {
  998. BaseWithContract baseWith = new SubWithoutContractNewProperties
  999. {
  1000. JustAProperty = "JustAProperty!",
  1001. Virtual = "Virtual!",
  1002. VirtualWithDataMember = "VirtualWithDataMember!",
  1003. WithDataMember = "WithDataMember!"
  1004. };
  1005. baseWith.JustAProperty = "JustAProperty2!";
  1006. baseWith.Virtual = "Virtual2!";
  1007. baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
  1008. baseWith.WithDataMember = "WithDataMember2!";
  1009. string json = AssertSerializeDeserializeEqual(baseWith);
  1010. Assert.AreEqual(@"{
  1011. ""JustAProperty"": ""JustAProperty2!"",
  1012. ""Virtual"": ""Virtual2!"",
  1013. ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
  1014. ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
  1015. ""WithDataMemberBase"": ""WithDataMember2!"",
  1016. ""WithDataMemberSub"": ""WithDataMember!""
  1017. }", json);
  1018. }
  1019. [Test]
  1020. public void SubWithoutContractVirtualPropertiesTest()
  1021. {
  1022. BaseWithContract baseWith = new SubWithoutContractVirtualProperties
  1023. {
  1024. JustAProperty = "JustAProperty!",
  1025. Virtual = "Virtual!",
  1026. VirtualWithDataMember = "VirtualWithDataMember!",
  1027. WithDataMember = "WithDataMember!"
  1028. };
  1029. baseWith.JustAProperty = "JustAProperty2!";
  1030. baseWith.Virtual = "Virtual2!";
  1031. baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
  1032. baseWith.WithDataMember = "WithDataMember2!";
  1033. string json = JsonConvert.SerializeObject(baseWith, Formatting.Indented);
  1034. Console.WriteLine(json);
  1035. Assert.AreEqual(@"{
  1036. ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
  1037. ""VirtualSub"": ""Virtual2!"",
  1038. ""WithDataMemberBase"": ""WithDataMember2!"",
  1039. ""JustAProperty"": ""JustAProperty2!""
  1040. }", json);
  1041. }
  1042. [Test]
  1043. public void SubWithContractNewPropertiesTest()
  1044. {
  1045. BaseWithContract baseWith = new SubWithContractNewProperties
  1046. {
  1047. JustAProperty = "JustAProperty!",
  1048. Virtual = "Virtual!",
  1049. VirtualWithDataMember = "VirtualWithDataMember!",
  1050. WithDataMember = "WithDataMember!"
  1051. };
  1052. baseWith.JustAProperty = "JustAProperty2!";
  1053. baseWith.Virtual = "Virtual2!";
  1054. baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
  1055. baseWith.WithDataMember = "WithDataMember2!";
  1056. string json = AssertSerializeDeserializeEqual(baseWith);
  1057. Assert.AreEqual(@"{
  1058. ""JustAProperty"": ""JustAProperty2!"",
  1059. ""JustAProperty2"": ""JustAProperty!"",
  1060. ""Virtual"": ""Virtual2!"",
  1061. ""Virtual2"": ""Virtual!"",
  1062. ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
  1063. ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
  1064. ""WithDataMemberBase"": ""WithDataMember2!"",
  1065. ""WithDataMemberSub"": ""WithDataMember!""
  1066. }", json);
  1067. }
  1068. [Test]
  1069. public void SubWithContractVirtualPropertiesTest()
  1070. {
  1071. BaseWithContract baseWith = new SubWithContractVirtualProperties
  1072. {
  1073. JustAProperty = "JustAProperty!",
  1074. Virtual = "Virtual!",
  1075. VirtualWithDataMember = "VirtualWithDataMember!",
  1076. WithDataMember = "WithDataMember!"
  1077. };
  1078. baseWith.JustAProperty = "JustAProperty2!";
  1079. baseWith.Virtual = "Virtual2!";
  1080. baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
  1081. baseWith.WithDataMember = "WithDataMember2!";
  1082. string json = AssertSerializeDeserializeEqual(baseWith);
  1083. Assert.AreEqual(@"{
  1084. ""JustAProperty"": ""JustAProperty2!"",
  1085. ""Virtual"": ""Virtual2!"",
  1086. ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
  1087. ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
  1088. ""WithDataMemberBase"": ""WithDataMember2!""
  1089. }", json);
  1090. }
  1091. private string AssertSerializeDeserializeEqual(object o)
  1092. {
  1093. MemoryStream ms = new MemoryStream();
  1094. DataContractJsonSerializer s = new DataContractJsonSerializer(o.GetType());
  1095. s.WriteObject(ms, o);
  1096. var data = ms.ToArray();
  1097. JObject dataContractJson = JObject.Parse(Encoding.UTF8.GetString(data, 0, data.Length));
  1098. dataContractJson = new JObject(dataContractJson.Properties().OrderBy(p => p.Name));
  1099. JObject jsonNetJson = JObject.Parse(JsonConvert.SerializeObject(o));
  1100. jsonNetJson = new JObject(jsonNetJson.Properties().OrderBy(p => p.Name));
  1101. Console.WriteLine("Results for " + o.GetType().Name);
  1102. Console.WriteLine("DataContractJsonSerializer: " + dataContractJson);
  1103. Console.WriteLine("JsonDotNetSerializer : " + jsonNetJson);
  1104. Assert.AreEqual(dataContractJson.Count, jsonNetJson.Count);
  1105. foreach (KeyValuePair<string, JToken> property in dataContractJson)
  1106. {
  1107. Assert.IsTrue(JToken.DeepEquals(jsonNetJson[property.Key], property.Value), "Property not equal: " + property.Key);
  1108. }
  1109. return jsonNetJson.ToString();
  1110. }
  1111. #endif
  1112. [Test]
  1113. public void PersonTypedObjectDeserialization()
  1114. {
  1115. Store store = new Store();
  1116. string jsonText = JsonConvert.SerializeObject(store);
  1117. Store deserializedStore = (Store)JsonConvert.DeserializeObject(jsonText, typeof(Store));
  1118. Assert.AreEqual(store.Establised, deserializedStore.Establised);
  1119. Assert.AreEqual(store.product.Count, deserializedStore.product.Count);
  1120. Console.WriteLine(jsonText);
  1121. }
  1122. [Test]
  1123. public void TypedObjectDeserialization()
  1124. {
  1125. Product product = new Product();
  1126. product.Name = "Apple";
  1127. product.ExpiryDate = new DateTime(2008, 12, 28);
  1128. product.Price = 3.99M;
  1129. product.Sizes = new string[] { "Small", "Medium", "Large" };
  1130. string output = JsonConvert.SerializeObject(product);
  1131. //{
  1132. // "Name": "Apple",
  1133. // "ExpiryDate": "\/Date(1230375600000+1300)\/",
  1134. // "Price": 3.99,
  1135. // "Sizes": [
  1136. // "Small",
  1137. // "Medium",
  1138. // "Large"
  1139. // ]
  1140. //}
  1141. Product deserializedProduct = (Product)JsonConvert.DeserializeObject(output, typeof(Product));
  1142. Assert.AreEqual("Apple", deserializedProduct.Name);
  1143. Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate);
  1144. Assert.AreEqual(3.99m, deserializedProduct.Price);
  1145. Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
  1146. Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
  1147. Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
  1148. }
  1149. //[Test]
  1150. //public void Advanced()
  1151. //{
  1152. // Product product = new Product();
  1153. // product.ExpiryDate = new DateTime(2008, 12, 28);
  1154. // JsonSerializer serializer = new JsonSerializer();
  1155. // serializer.Converters.Add(new JavaScriptDateTimeConverter());
  1156. // serializer.NullValueHandling = NullValueHandling.Ignore;
  1157. // using (StreamWriter sw = new StreamWriter(@"c:\json.txt"))
  1158. // using (JsonWriter writer = new JsonTextWriter(sw))
  1159. // {
  1160. // serializer.Serialize(writer, product);
  1161. // // {"ExpiryDate":new Date(1230375600000),"Price":0}
  1162. // }
  1163. //}
  1164. [Test]
  1165. public void JsonConvertSerializer()
  1166. {
  1167. string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
  1168. Product p = JsonConvert.DeserializeObject(value, typeof(Product)) as Product;
  1169. Assert.AreEqual("Orange", p.Name);
  1170. Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.ExpiryDate);
  1171. Assert.AreEqual(3.99m, p.Price);
  1172. }
  1173. [Test]
  1174. public void DeserializeJavaScriptDate()
  1175. {
  1176. DateTime dateValue = new DateTime(2010, 3, 30);
  1177. Dictionary<string, object> testDictionary = new Dictionary<string, object>();
  1178. testDictionary["date"] = dateValue;
  1179. string jsonText = JsonConvert.SerializeObject(testDictionary);
  1180. #if !NET20
  1181. MemoryStream ms = new MemoryStream();
  1182. DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<string, object>));
  1183. serializer.WriteObject(ms, testDictionary);
  1184. byte[] data = ms.ToArray();
  1185. string output = Encoding.UTF8.GetString(data, 0, data.Length);
  1186. #endif
  1187. Dictionary<string, object> deserializedDictionary = (Dictionary<string, object>)JsonConvert.DeserializeObject(jsonText, typeof(Dictionary<string, object>));
  1188. DateTime deserializedDate = (DateTime)deserializedDictionary["date"];
  1189. Assert.AreEqual(dateValue, deserializedDate);
  1190. }
  1191. [Test]
  1192. public void TestMethodExecutorObject()
  1193. {
  1194. MethodExecutorObject executorObject = new MethodExecutorObject();
  1195. executorObject.serverClassName = "BanSubs";
  1196. executorObject.serverMethodParams = new object[] { "21321546", "101", "1236", "D:\\1.txt" };
  1197. executorObject.clientGetResultFunction = "ClientBanSubsCB";
  1198. string output = JsonConvert.SerializeObject(executorObject);
  1199. MethodExecutorObject executorObject2 = JsonConvert.DeserializeObject(output, typeof(MethodExecutorObject)) as MethodExecutorObject;
  1200. Assert.AreNotSame(executorObject, executorObject2);
  1201. Assert.AreEqual(executorObject2.serverClassName, "BanSubs");
  1202. Assert.AreEqual(executorObject2.serverMethodParams.Length, 4);
  1203. CustomAssert.Contains(executorObject2.serverMethodParams, "101");
  1204. Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB");
  1205. }
  1206. #if !NETFX_CORE
  1207. [Test]
  1208. public void HashtableDeserialization()
  1209. {
  1210. string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
  1211. Hashtable p = JsonConvert.DeserializeObject(value, typeof(Hashtable)) as Hashtable;
  1212. Assert.AreEqual("Orange", p["Name"].ToString());
  1213. }
  1214. [Test]
  1215. public void TypedHashtableDeserialization()
  1216. {
  1217. string value = @"{""Name"":""Orange"", ""Hash"":{""ExpiryDate"":""01/24/2010 12:00:00"",""UntypedArray"":[""01/24/2010 12:00:00""]}}";
  1218. TypedSubHashtable p = JsonConvert.DeserializeObject(value, typeof(TypedSubHashtable)) as TypedSubHashtable;
  1219. Assert.AreEqual("01/24/2010 12:00:00", p.Hash["ExpiryDate"].ToString());
  1220. Assert.AreEqual(@"[
  1221. ""01/24/2010 12:00:00""
  1222. ]", p.Hash["UntypedArray"].ToString());
  1223. }
  1224. #endif
  1225. [Test]
  1226. public void SerializeDeserializeGetOnlyProperty()
  1227. {
  1228. string value = JsonConvert.SerializeObject(new GetOnlyPropertyClass());
  1229. GetOnlyPropertyClass c = JsonConvert.DeserializeObject<GetOnlyPropertyClass>(value);
  1230. Assert.AreEqual(c.Field, "Field");
  1231. Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty");
  1232. }
  1233. [Test]
  1234. public void SerializeDeserializeSetOnlyProperty()
  1235. {
  1236. string value = JsonConvert.SerializeObject(new SetOnlyPropertyClass());
  1237. SetOnlyPropertyClass c = JsonConvert.DeserializeObject<SetOnlyPropertyClass>(value);
  1238. Assert.AreEqual(c.Field, "Field");
  1239. }
  1240. [Test]
  1241. public void JsonIgnoreAttributeTest()
  1242. {
  1243. string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeTestClass());
  1244. Assert.AreEqual(@"{""Field"":0,""Property"":21}", json);
  1245. JsonIgnoreAttributeTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeTestClass>(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1,""IgnoredObject"":[1,2,3,4,5]}");
  1246. Assert.AreEqual(0, c.IgnoredField);
  1247. Assert.AreEqual(99, c.Field);
  1248. }
  1249. [Test]
  1250. public void GoogleSearchAPI()
  1251. {
  1252. string json = @"{
  1253. results:
  1254. [
  1255. {
  1256. GsearchResultClass:""GwebSearch"",
  1257. unescapedUrl : ""http://www.google.com/"",
  1258. url : ""http://www.google.com/"",
  1259. visibleUrl : ""www.google.com"",
  1260. cacheUrl :
  1261. ""http://www.google.com/search?q=cache:zhool8dxBV4J:www.google.com"",
  1262. title : ""Google"",
  1263. titleNoFormatting : ""Google"",
  1264. content : ""Enables users to search the Web, Usenet, and
  1265. images. Features include PageRank, caching and translation of
  1266. results, and an option to find similar pages.""
  1267. },
  1268. {
  1269. GsearchResultClass:""GwebSearch"",
  1270. unescapedUrl : ""http://news.google.com/"",
  1271. url : ""http://news.google.com/"",
  1272. visibleUrl : ""news.google.com"",
  1273. cacheUrl :
  1274. ""http://www.google.com/search?q=cache:Va_XShOz_twJ:news.google.com"",
  1275. title : ""Google News"",
  1276. titleNoFormatting : ""Google News"",
  1277. content : ""Aggregated headlines and a search engine of many of the world's news sources.""
  1278. },
  1279. {
  1280. GsearchResultClass:""GwebSearch"",
  1281. unescapedUrl : ""http://groups.google.com/"",
  1282. url : ""http://groups.google.com/"",
  1283. visibleUrl : ""groups.google.com"",
  1284. cacheUrl :
  1285. ""http://www.google.com/search?q=cache:x2uPD3hfkn0J:groups.google.com"",
  1286. title : ""Google Groups"",
  1287. titleNoFormatting : ""Google Groups"",
  1288. content : ""Enables users to search and browse the Usenet
  1289. archives which consist of over 700 million messages, and post new
  1290. comments.""
  1291. },
  1292. {
  1293. GsearchResultClass:""GwebSearch"",
  1294. unescapedUrl : ""http://maps.google.com/"",
  1295. url : ""http://maps.google.com/"",
  1296. visibleUrl : ""maps.google.com"",
  1297. cacheUrl :
  1298. ""http://www.google.com/search?q=cache:dkf5u2twBXIJ:maps.google.com"",
  1299. title : ""Google Maps"",
  1300. titleNoFormatting : ""Google Maps"",
  1301. content : ""Provides directions, interactive maps, and
  1302. satellite/aerial imagery of the United States. Can also search by
  1303. keyword such as type of business.""
  1304. }
  1305. ],
  1306. adResults:
  1307. [
  1308. {
  1309. GsearchResultClass:""GwebSearch.ad"",
  1310. title : ""Gartner Symposium/ITxpo"",
  1311. content1 : ""Meet brilliant Gartner IT analysts"",
  1312. content2 : ""20-23 May 2007- Barcelona, Spain"",
  1313. url :
  1314. ""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="",
  1315. impressionUrl :
  1316. ""http://www.google.com/uds/css/ad-indicator-on.gif?ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB"",
  1317. unescapedUrl :
  1318. ""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="",
  1319. visibleUrl : ""www.gartner.com""
  1320. }
  1321. ]
  1322. }
  1323. ";
  1324. object o = JsonConvert.DeserializeObject(json);
  1325. string s = string.Empty;
  1326. s += s;
  1327. }
  1328. [Test]
  1329. public void TorrentDeserializeTest()
  1330. {
  1331. string jsonText = @"{
  1332. """":"""",
  1333. ""label"": [
  1334. [""SomeName"",6]
  1335. ],
  1336. ""torrents"": [
  1337. [""192D99A5C943555CB7F00A852821CF6D6DB3008A"",201,""filename.avi"",178311826,1000,178311826,72815250,408,1603,7,121430,""NameOfLabelPrevioslyDefined"",3,6,0,8,128954,-1,0],
  1338. ],
  1339. ""torrentc"": ""1816000723""
  1340. }";
  1341. JObject o = (JObject)JsonConvert.DeserializeObject(jsonText);
  1342. Assert.AreEqual(4, o.Children().Count());
  1343. JToken torrentsArray = (JToken)o["torrents"];
  1344. JToken nestedTorrentsArray = (JToken)torrentsArray[0];
  1345. Assert.AreEqual(nestedTorrentsArray.Children().Count(), 19);
  1346. }
  1347. [Test]
  1348. public void JsonPropertyClassSerialize()
  1349. {
  1350. JsonPropertyClass test = new JsonPropertyClass();
  1351. test.Pie = "Delicious";
  1352. test.SweetCakesCount = int.MaxValue;
  1353. string jsonText = JsonConvert.SerializeObject(test);
  1354. Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText);
  1355. JsonPropertyClass test2 = JsonConvert.DeserializeObject<JsonPropertyClass>(jsonText);
  1356. Assert.AreEqual(test.Pie, test2.Pie);
  1357. Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount);
  1358. }
  1359. [Test]
  1360. public void BadJsonPropertyClassSerialize()
  1361. {
  1362. ExceptionAssert.Throws<JsonSerializationException>(
  1363. @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.",
  1364. () => { JsonConvert.SerializeObject(new BadJsonPropertyClass()); });
  1365. }
  1366. [Test]
  1367. public void InheritedListSerialize()
  1368. {
  1369. Article a1 = new Article("a1");
  1370. Article a2 = new Article("a2");
  1371. ArticleCollection articles1 = new ArticleCollection();
  1372. articles1.Add(a1);
  1373. articles1.Add(a2);
  1374. string jsonText = JsonConvert.SerializeObject(articles1);
  1375. ArticleCollection articles2 = JsonConvert.DeserializeObject<ArticleCollection>(jsonText);
  1376. Assert.AreEqual(articles1.Count, articles2.Count);
  1377. Assert.AreEqual(articles1[0].Name, articles2[0].Name);
  1378. }
  1379. [Test]
  1380. public void ReadOnlyCollectionSerialize()
  1381. {
  1382. ReadOnlyCollection<int> r1 = new ReadOnlyCollection<int>(new int[] { 0, 1, 2, 3, 4 });
  1383. string jsonText = JsonConvert.SerializeObject(r1);
  1384. Assert.AreEqual("[0,1,2,3,4]", jsonText);
  1385. ReadOnlyCollection<int> r2 = JsonConvert.DeserializeObject<ReadOnlyCollection<int>>(jsonText);
  1386. CollectionAssert.AreEqual(r1, r2);
  1387. }
  1388. #if !NET20
  1389. [Test]
  1390. public void Unicode()
  1391. {
  1392. string json = @"[""PRE\u003cPOST""]";
  1393. DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
  1394. List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
  1395. List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
  1396. Assert.AreEqual(1, jsonNetResult.Count);
  1397. Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
  1398. }
  1399. [Test]
  1400. public void BackslashEqivilence()
  1401. {
  1402. string json = @"[""vvv\/vvv\tvvv\""vvv\bvvv\nvvv\rvvv\\vvv\fvvv""]";
  1403. #if !NETFX_CORE
  1404. JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
  1405. List<string> javaScriptSerializerResult = javaScriptSerializer.Deserialize<List<string>>(json);
  1406. #endif
  1407. DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
  1408. List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
  1409. List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
  1410. Assert.AreEqual(1, jsonNetResult.Count);
  1411. Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
  1412. #if !NETFX_CORE
  1413. Assert.AreEqual(javaScriptSerializerResult[0], jsonNetResult[0]);
  1414. #endif
  1415. }
  1416. [Test]
  1417. public void InvalidBackslash()
  1418. {
  1419. string json = @"[""vvv\jvvv""]";
  1420. ExceptionAssert.Throws<JsonReaderException>(
  1421. @"Bad JSON escape sequence: \j. Path '', line 1, position 7.",
  1422. () => { JsonConvert.DeserializeObject<List<string>>(json); });
  1423. }
  1424. [Test]
  1425. public void DateTimeTest()
  1426. {
  1427. List<DateTime> testDates = new List<DateTime>
  1428. {
  1429. new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Local),
  1430. new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
  1431. new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc),
  1432. new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local),
  1433. new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
  1434. new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc),
  1435. };
  1436. MemoryStream ms = new MemoryStream();
  1437. DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<DateTime>));
  1438. s.WriteObject(ms, testDates);
  1439. ms.Seek(0, SeekOrigin.Begin);
  1440. StreamReader sr = new StreamReader(ms);
  1441. string expected = sr.ReadToEnd();
  1442. string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat });
  1443. Assert.AreEqual(expected, result);
  1444. }
  1445. [Test]
  1446. public void DateTimeOffsetIso()
  1447. {
  1448. List<DateTimeOffset> testDates = new List<DateTimeOffset>
  1449. {
  1450. new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
  1451. new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
  1452. new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
  1453. new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
  1454. };
  1455. string result = JsonConvert.SerializeObject(testDates);
  1456. Assert.AreEqual(@"[""0100-01-01T01:01:01+00:00"",""2000-01-01T01:01:01+00:00"",""2000-01-01T01:01:01+13:00"",""2000-01-01T01:01:01-03:30""]", result);
  1457. }
  1458. [Test]
  1459. public void DateTimeOffsetMsAjax()
  1460. {
  1461. List<DateTimeOffset> testDates = new List<DateTimeOffset>
  1462. {
  1463. new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
  1464. new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
  1465. new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
  1466. new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
  1467. };
  1468. string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat });
  1469. Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result);
  1470. }
  1471. #endif
  1472. [Test]
  1473. public void NonStringKeyDictionary()
  1474. {
  1475. Dictionary<int, int> values = new Dictionary<int, int>();
  1476. values.Add(-5, 6);
  1477. values.Add(int.MinValue, int.MaxValue);
  1478. string json = JsonConvert.SerializeObject(values);
  1479. Assert.AreEqual(@"{""-5"":6,""-2147483648"":2147483647}", json);
  1480. Dictionary<int, int> newValues = JsonConvert.DeserializeObject<Dictionary<int, int>>(json);
  1481. CollectionAssert.AreEqual(values, newValues);
  1482. }
  1483. [Test]
  1484. public void AnonymousObjectSerialization()
  1485. {
  1486. var anonymous =
  1487. new
  1488. {
  1489. StringValue = "I am a string",
  1490. IntValue = int.MaxValue,
  1491. NestedAnonymous = new { NestedValue = byte.MaxValue },
  1492. NestedArray = new[] { 1, 2 },
  1493. Product = new Product() { Name = "TestProduct" }
  1494. };
  1495. string json = JsonConvert.SerializeObject(anonymous);
  1496. Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647,""NestedAnonymous"":{""NestedValue"":255},""NestedArray"":[1,2],""Product"":{""Name"":""TestProduct"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}}", json);
  1497. anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous);
  1498. Assert.AreEqual("I am a string", anonymous.StringValue);
  1499. Assert.AreEqual(int.MaxValue, anonymous.IntValue);
  1500. Assert.AreEqual(255, anonymous.NestedAnonymous.NestedValue);
  1501. Assert.AreEqual(2, anonymous.NestedArray.Length);
  1502. Assert.AreEqual(1, anonymous.NestedArray[0]);
  1503. Assert.AreEqual(2, anonymous.NestedArray[1]);
  1504. Assert.AreEqual("TestProduct", anonymous.Product.Name);
  1505. }
  1506. [Test]
  1507. public void AnonymousObjectSerializationWithSetting()
  1508. {
  1509. DateTime d = new DateTime(2000, 1, 1);
  1510. var anonymous =
  1511. new
  1512. {
  1513. DateValue = d
  1514. };
  1515. JsonSerializerSettings settings = new JsonSerializerSettings();
  1516. settings.Converters.Add(new IsoDateTimeConverter
  1517. {
  1518. DateTimeFormat = "yyyy"
  1519. });
  1520. string json = JsonConvert.SerializeObject(anonymous, settings);
  1521. Assert.AreEqual(@"{""DateValue"":""2000""}", json);
  1522. anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous, settings);
  1523. Assert.AreEqual(d, anonymous.DateValue);
  1524. }
  1525. [Test]
  1526. public void CustomCollectionSerialization()
  1527. {
  1528. ProductCollection collection = new ProductCollection()
  1529. {
  1530. new Product() { Name = "Test1" },
  1531. new Product() { Name = "Test2" },
  1532. new Product() { Name = "Test3" }
  1533. };
  1534. JsonSerializer jsonSerializer = new JsonSerializer();
  1535. jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  1536. StringWriter sw = new StringWriter();
  1537. jsonSerializer.Serialize(sw, collection);
  1538. Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}]",
  1539. sw.GetStringBuilder().ToString());
  1540. ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection));
  1541. CollectionAssert.AreEqual(collection, collectionNew);
  1542. }
  1543. [Test]
  1544. public void SerializeObject()
  1545. {
  1546. string json = JsonConvert.SerializeObject(new object());
  1547. Assert.AreEqual("{}", json);
  1548. }
  1549. [Test]
  1550. public void SerializeNull()
  1551. {
  1552. string json = JsonConvert.SerializeObject(null);
  1553. Assert.AreEqual("null", json);
  1554. }
  1555. [Test]
  1556. public void CanDeserializeIntArrayWhenNotFirstPropertyInJson()
  1557. {
  1558. string json = "{foo:'hello',bar:[1,2,3]}";
  1559. ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
  1560. Assert.AreEqual("hello", wibble.Foo);
  1561. Assert.AreEqual(4, wibble.Bar.Count);
  1562. Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
  1563. Assert.AreEqual(1, wibble.Bar[1]);
  1564. Assert.AreEqual(2, wibble.Bar[2]);
  1565. Assert.AreEqual(3, wibble.Bar[3]);
  1566. }
  1567. [Test]
  1568. public void CanDeserializeIntArray_WhenArrayIsFirstPropertyInJson()
  1569. {
  1570. string json = "{bar:[1,2,3], foo:'hello'}";
  1571. ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
  1572. Assert.AreEqual("hello", wibble.Foo);
  1573. Assert.AreEqual(4, wibble.Bar.Count);
  1574. Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
  1575. Assert.AreEqual(1, wibble.Bar[1]);
  1576. Assert.AreEqual(2, wibble.Bar[2]);
  1577. Assert.AreEqual(3, wibble.Bar[3]);
  1578. }
  1579. [Test]
  1580. public void ObjectCreationHandlingReplace()
  1581. {
  1582. string json = "{bar:[1,2,3], foo:'hello'}";
  1583. JsonSerializer s = new JsonSerializer();
  1584. s.ObjectCreationHandling = ObjectCreationHandling.Replace;
  1585. ClassWithArray wibble = (ClassWithArray)s.Deserialize(new StringReader(json), typeof(ClassWithArray));
  1586. Assert.AreEqual("hello", wibble.Foo);
  1587. Assert.AreEqual(1, wibble.Bar.Count);
  1588. }
  1589. [Test]
  1590. public void CanDeserializeSerializedJson()
  1591. {
  1592. ClassWithArray wibble = new ClassWithArray();
  1593. wibble.Foo = "hello";
  1594. wibble.Bar.Add(1);
  1595. wibble.Bar.Add(2);
  1596. wibble.Bar.Add(3);
  1597. string json = JsonConvert.SerializeObject(wibble);
  1598. ClassWithArray wibbleOut = JsonConvert.DeserializeObject<ClassWithArray>(json);
  1599. Assert.AreEqual("hello", wibbleOut.Foo);
  1600. Assert.AreEqual(5, wibbleOut.Bar.Count);
  1601. Assert.AreEqual(int.MaxValue, wibbleOut.Bar[0]);
  1602. Assert.AreEqual(int.MaxValue, wibbleOut.Bar[1]);
  1603. Assert.AreEqual(1, wibbleOut.Bar[2]);
  1604. Assert.AreEqual(2, wibbleOut.Bar[3]);
  1605. Assert.AreEqual(3, wibbleOut.Bar[4]);
  1606. }
  1607. [Test]
  1608. public void SerializeConverableObjects()
  1609. {
  1610. string json = JsonConvert.SerializeObject(new ConverableMembers(), Formatting.Indented);
  1611. string expected = null;
  1612. #if !(NETFX_CORE || PORTABLE)
  1613. expected = @"{
  1614. ""String"": ""string"",
  1615. ""Int32"": 2147483647,
  1616. ""UInt32"": 4294967295,
  1617. ""Byte"": 255,
  1618. ""SByte"": 127,
  1619. ""Short"": 32767,
  1620. ""UShort"": 65535,
  1621. ""Long"": 9223372036854775807,
  1622. ""ULong"": 9223372036854775807,
  1623. ""Double"": 1.7976931348623157E+308,
  1624. ""Float"": 3.40282347E+38,
  1625. ""DBNull"": null,
  1626. ""Bool"": true,
  1627. ""Char"": ""\u0000""
  1628. }";
  1629. #else
  1630. expected = @"{
  1631. ""String"": ""string"",
  1632. ""Int32"": 2147483647,
  1633. ""UInt32"": 4294967295,
  1634. ""Byte"": 255,
  1635. ""SByte"": 127,
  1636. ""Short"": 32767,
  1637. ""UShort"": 65535,
  1638. ""Long"": 9223372036854775807,
  1639. ""ULong"": 9223372036854775807,
  1640. ""Double"": 1.7976931348623157E+308,
  1641. ""Float"": 3.40282347E+38,
  1642. ""Bool"": true,
  1643. ""Char"": ""\u0000""
  1644. }";
  1645. #endif
  1646. Assert.AreEqual(expected, json);
  1647. ConverableMembers c = JsonConvert.DeserializeObject<ConverableMembers>(json);
  1648. Assert.AreEqual("string", c.String);
  1649. Assert.AreEqual(double.MaxValue, c.Double);
  1650. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  1651. Assert.AreEqual(DBNull.Value, c.DBNull);
  1652. #endif
  1653. }
  1654. [Test]
  1655. public void SerializeStack()
  1656. {
  1657. Stack<object> s = new Stack<object>();
  1658. s.Push(1);
  1659. s.Push(2);
  1660. s.Push(3);
  1661. string json = JsonConvert.SerializeObject(s);
  1662. Assert.AreEqual("[3,2,1]", json);
  1663. }
  1664. [Test]
  1665. public void FormattingOverride()
  1666. {
  1667. var obj = new { Formatting = "test" };
  1668. JsonSerializerSettings settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
  1669. string indented = JsonConvert.SerializeObject(obj, settings);
  1670. string none = JsonConvert.SerializeObject(obj, Formatting.None, settings);
  1671. Assert.AreNotEqual(indented, none);
  1672. }
  1673. [Test]
  1674. public void DateTimeTimeZone()
  1675. {
  1676. var date = new DateTime(2001, 4, 4, 0, 0, 0, DateTimeKind.Utc);
  1677. string json = JsonConvert.SerializeObject(date);
  1678. Assert.AreEqual(@"""2001-04-04T00:00:00Z""", json);
  1679. }
  1680. [Test]
  1681. public void GuidTest()
  1682. {
  1683. Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D");
  1684. string json = JsonConvert.SerializeObject(new ClassWithGuid { GuidField = guid });
  1685. Assert.AreEqual(@"{""GuidField"":""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""}", json);
  1686. ClassWithGuid c = JsonConvert.DeserializeObject<ClassWithGuid>(json);
  1687. Assert.AreEqual(guid, c.GuidField);
  1688. }
  1689. [Test]
  1690. public void EnumTest()
  1691. {
  1692. string json = JsonConvert.SerializeObject(StringComparison.CurrentCultureIgnoreCase);
  1693. Assert.AreEqual(@"1", json);
  1694. StringComparison s = JsonConvert.DeserializeObject<StringComparison>(json);
  1695. Assert.AreEqual(StringComparison.CurrentCultureIgnoreCase, s);
  1696. }
  1697. public class ClassWithTimeSpan
  1698. {
  1699. public TimeSpan TimeSpanField;
  1700. }
  1701. [Test]
  1702. public void TimeSpanTest()
  1703. {
  1704. TimeSpan ts = new TimeSpan(00, 23, 59, 1);
  1705. string json = JsonConvert.SerializeObject(new ClassWithTimeSpan { TimeSpanField = ts }, Formatting.Indented);
  1706. Assert.AreEqual(@"{
  1707. ""TimeSpanField"": ""23:59:01""
  1708. }", json);
  1709. ClassWithTimeSpan c = JsonConvert.DeserializeObject<ClassWithTimeSpan>(json);
  1710. Assert.AreEqual(ts, c.TimeSpanField);
  1711. }
  1712. [Test]
  1713. public void JsonIgnoreAttributeOnClassTest()
  1714. {
  1715. string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeOnClassTestClass());
  1716. Assert.AreEqual(@"{""TheField"":0,""Property"":21}", json);
  1717. JsonIgnoreAttributeOnClassTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeOnClassTestClass>(@"{""TheField"":99,""Property"":-1,""IgnoredField"":-1}");
  1718. Assert.AreEqual(0, c.IgnoredField);
  1719. Assert.AreEqual(99, c.Field);
  1720. }
  1721. #if !NETFX_CORE
  1722. [Test]
  1723. public void SerializeArrayAsArrayList()
  1724. {
  1725. string jsonText = @"[3, ""somestring"",[1,2,3],{}]";
  1726. ArrayList o = JsonConvert.DeserializeObject<ArrayList>(jsonText);
  1727. Assert.AreEqual(4, o.Count);
  1728. Assert.AreEqual(3, ((JArray)o[2]).Count);
  1729. Assert.AreEqual(0, ((JObject)o[3]).Count);
  1730. }
  1731. #endif
  1732. [Test]
  1733. public void SerializeMemberGenericList()
  1734. {
  1735. Name name = new Name("The Idiot in Next To Me");
  1736. PhoneNumber p1 = new PhoneNumber("555-1212");
  1737. PhoneNumber p2 = new PhoneNumber("444-1212");
  1738. name.pNumbers.Add(p1);
  1739. name.pNumbers.Add(p2);
  1740. string json = JsonConvert.SerializeObject(name, Formatting.Indented);
  1741. Assert.AreEqual(@"{
  1742. ""personsName"": ""The Idiot in Next To Me"",
  1743. ""pNumbers"": [
  1744. {
  1745. ""phoneNumber"": ""555-1212""
  1746. },
  1747. {
  1748. ""phoneNumber"": ""444-1212""
  1749. }
  1750. ]
  1751. }", json);
  1752. Name newName = JsonConvert.DeserializeObject<Name>(json);
  1753. Assert.AreEqual("The Idiot in Next To Me", newName.personsName);
  1754. // not passed in as part of the constructor but assigned to pNumbers property
  1755. Assert.AreEqual(2, newName.pNumbers.Count);
  1756. Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber);
  1757. Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber);
  1758. }
  1759. [Test]
  1760. public void ConstructorCaseSensitivity()
  1761. {
  1762. ConstructorCaseSensitivityClass c = new ConstructorCaseSensitivityClass("param1", "Param1", "Param2");
  1763. string json = JsonConvert.SerializeObject(c);
  1764. ConstructorCaseSensitivityClass deserialized = JsonConvert.DeserializeObject<ConstructorCaseSensitivityClass>(json);
  1765. Assert.AreEqual("param1", deserialized.param1);
  1766. Assert.AreEqual("Param1", deserialized.Param1);
  1767. Assert.AreEqual("Param2", deserialized.Param2);
  1768. }
  1769. [Test]
  1770. public void SerializerShouldUseClassConverter()
  1771. {
  1772. ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
  1773. string json = JsonConvert.SerializeObject(c1);
  1774. Assert.AreEqual(@"[""Class"",""!Test!""]", json);
  1775. ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json);
  1776. Assert.AreEqual("!Test!", c2.TestValue);
  1777. }
  1778. [Test]
  1779. public void SerializerShouldUseClassConverterOverArgumentConverter()
  1780. {
  1781. ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
  1782. string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
  1783. Assert.AreEqual(@"[""Class"",""!Test!""]", json);
  1784. ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json, new ArgumentConverterPrecedenceClassConverter());
  1785. Assert.AreEqual("!Test!", c2.TestValue);
  1786. }
  1787. [Test]
  1788. public void SerializerShouldUseMemberConverter_IsoDate()
  1789. {
  1790. DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
  1791. MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
  1792. string json = JsonConvert.SerializeObject(m1);
  1793. Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
  1794. MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
  1795. Assert.AreEqual(testDate, m2.DefaultConverter);
  1796. Assert.AreEqual(testDate, m2.MemberConverter);
  1797. }
  1798. [Test]
  1799. public void SerializerShouldUseMemberConverter_MsDate()
  1800. {
  1801. DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
  1802. MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
  1803. string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings
  1804. {
  1805. DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
  1806. });
  1807. Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
  1808. MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
  1809. Assert.AreEqual(testDate, m2.DefaultConverter);
  1810. Assert.AreEqual(testDate, m2.MemberConverter);
  1811. }
  1812. [Test]
  1813. public void SerializerShouldUseMemberConverter_MsDate_DateParseNone()
  1814. {
  1815. DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
  1816. MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
  1817. string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings
  1818. {
  1819. DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
  1820. });
  1821. Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
  1822. var m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json, new JsonSerializerSettings
  1823. {
  1824. DateParseHandling = DateParseHandling.None
  1825. });
  1826. Assert.AreEqual(new DateTime(1970, 1, 1), m2.DefaultConverter);
  1827. Assert.AreEqual(new DateTime(1970, 1, 1), m2.MemberConverter);
  1828. }
  1829. [Test]
  1830. public void SerializerShouldUseMemberConverter_IsoDate_DateParseNone()
  1831. {
  1832. DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
  1833. MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
  1834. string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings
  1835. {
  1836. DateFormatHandling = DateFormatHandling.IsoDateFormat,
  1837. });
  1838. Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
  1839. MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
  1840. Assert.AreEqual(testDate, m2.DefaultConverter);
  1841. Assert.AreEqual(testDate, m2.MemberConverter);
  1842. }
  1843. [Test]
  1844. public void SerializerShouldUseMemberConverterOverArgumentConverter()
  1845. {
  1846. DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
  1847. MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
  1848. string json = JsonConvert.SerializeObject(m1, new JavaScriptDateTimeConverter());
  1849. Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
  1850. MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json, new JavaScriptDateTimeConverter());
  1851. Assert.AreEqual(testDate, m2.DefaultConverter);
  1852. Assert.AreEqual(testDate, m2.MemberConverter);
  1853. }
  1854. [Test]
  1855. public void ConverterAttributeExample()
  1856. {
  1857. DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
  1858. MemberConverterClass c = new MemberConverterClass
  1859. {
  1860. DefaultConverter = date,
  1861. MemberConverter = date
  1862. };
  1863. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  1864. Console.WriteLine(json);
  1865. //{
  1866. // "DefaultConverter": "\/Date(0)\/",
  1867. // "MemberConverter": "1970-01-01T00:00:00Z"
  1868. //}
  1869. }
  1870. [Test]
  1871. public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter()
  1872. {
  1873. ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass();
  1874. c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue");
  1875. c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue");
  1876. string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
  1877. Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json);
  1878. ClassAndMemberConverterClass c2 = JsonConvert.DeserializeObject<ClassAndMemberConverterClass>(json, new ArgumentConverterPrecedenceClassConverter());
  1879. Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue);
  1880. Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue);
  1881. }
  1882. [Test]
  1883. public void IncompatibleJsonAttributeShouldThrow()
  1884. {
  1885. ExceptionAssert.Throws<JsonSerializationException>(
  1886. "Unexpected value when converting date. Expected DateTime or DateTimeOffset, got Newtonsoft.Json.Tests.TestObjects.IncompatibleJsonAttributeClass.",
  1887. () =>
  1888. {
  1889. IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass();
  1890. JsonConvert.SerializeObject(c);
  1891. });
  1892. }
  1893. [Test]
  1894. public void GenericAbstractProperty()
  1895. {
  1896. string json = JsonConvert.SerializeObject(new GenericImpl());
  1897. Assert.AreEqual(@"{""Id"":0}", json);
  1898. }
  1899. [Test]
  1900. public void DeserializeNullable()
  1901. {
  1902. string json;
  1903. json = JsonConvert.SerializeObject((int?)null);
  1904. Assert.AreEqual("null", json);
  1905. json = JsonConvert.SerializeObject((int?)1);
  1906. Assert.AreEqual("1", json);
  1907. }
  1908. [Test]
  1909. public void SerializeJsonRaw()
  1910. {
  1911. PersonRaw personRaw = new PersonRaw
  1912. {
  1913. FirstName = "FirstNameValue",
  1914. RawContent = new JRaw("[1,2,3,4,5]"),
  1915. LastName = "LastNameValue"
  1916. };
  1917. string json;
  1918. json = JsonConvert.SerializeObject(personRaw);
  1919. Assert.AreEqual(@"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}", json);
  1920. }
  1921. [Test]
  1922. public void DeserializeJsonRaw()
  1923. {
  1924. string json = @"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}";
  1925. PersonRaw personRaw = JsonConvert.DeserializeObject<PersonRaw>(json);
  1926. Assert.AreEqual("FirstNameValue", personRaw.FirstName);
  1927. Assert.AreEqual("[1,2,3,4,5]", personRaw.RawContent.ToString());
  1928. Assert.AreEqual("LastNameValue", personRaw.LastName);
  1929. }
  1930. [Test]
  1931. public void DeserializeNullableMember()
  1932. {
  1933. UserNullable userNullablle = new UserNullable
  1934. {
  1935. Id = new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"),
  1936. FName = "FirstValue",
  1937. LName = "LastValue",
  1938. RoleId = 5,
  1939. NullableRoleId = 6,
  1940. NullRoleId = null,
  1941. Active = true
  1942. };
  1943. string json = JsonConvert.SerializeObject(userNullablle);
  1944. Assert.AreEqual(@"{""Id"":""ad6205e8-0df4-465d-aea6-8ba18e93a7e7"",""FName"":""FirstValue"",""LName"":""LastValue"",""RoleId"":5,""NullableRoleId"":6,""NullRoleId"":null,""Active"":true}", json);
  1945. UserNullable userNullablleDeserialized = JsonConvert.DeserializeObject<UserNullable>(json);
  1946. Assert.AreEqual(new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), userNullablleDeserialized.Id);
  1947. Assert.AreEqual("FirstValue", userNullablleDeserialized.FName);
  1948. Assert.AreEqual("LastValue", userNullablleDeserialized.LName);
  1949. Assert.AreEqual(5, userNullablleDeserialized.RoleId);
  1950. Assert.AreEqual(6, userNullablleDeserialized.NullableRoleId);
  1951. Assert.AreEqual(null, userNullablleDeserialized.NullRoleId);
  1952. Assert.AreEqual(true, userNullablleDeserialized.Active);
  1953. }
  1954. [Test]
  1955. public void DeserializeInt64ToNullableDouble()
  1956. {
  1957. string json = @"{""Height"":1}";
  1958. DoubleClass c = JsonConvert.DeserializeObject<DoubleClass>(json);
  1959. Assert.AreEqual(1, c.Height);
  1960. }
  1961. [Test]
  1962. public void SerializeTypeProperty()
  1963. {
  1964. string boolRef = typeof(bool).AssemblyQualifiedName;
  1965. TypeClass typeClass = new TypeClass { TypeProperty = typeof(bool) };
  1966. string json = JsonConvert.SerializeObject(typeClass);
  1967. Assert.AreEqual(@"{""TypeProperty"":""" + boolRef + @"""}", json);
  1968. TypeClass typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
  1969. Assert.AreEqual(typeof(bool), typeClass2.TypeProperty);
  1970. string jsonSerializerTestRef = typeof(JsonSerializerTest).AssemblyQualifiedName;
  1971. typeClass = new TypeClass { TypeProperty = typeof(JsonSerializerTest) };
  1972. json = JsonConvert.SerializeObject(typeClass);
  1973. Assert.AreEqual(@"{""TypeProperty"":""" + jsonSerializerTestRef + @"""}", json);
  1974. typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
  1975. Assert.AreEqual(typeof(JsonSerializerTest), typeClass2.TypeProperty);
  1976. }
  1977. [Test]
  1978. public void RequiredMembersClass()
  1979. {
  1980. RequiredMembersClass c = new RequiredMembersClass()
  1981. {
  1982. BirthDate = new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc),
  1983. FirstName = "Bob",
  1984. LastName = "Smith",
  1985. MiddleName = "Cosmo"
  1986. };
  1987. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  1988. Assert.AreEqual(@"{
  1989. ""FirstName"": ""Bob"",
  1990. ""MiddleName"": ""Cosmo"",
  1991. ""LastName"": ""Smith"",
  1992. ""BirthDate"": ""2000-12-20T10:55:55Z""
  1993. }", json);
  1994. RequiredMembersClass c2 = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
  1995. Assert.AreEqual("Bob", c2.FirstName);
  1996. Assert.AreEqual(new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), c2.BirthDate);
  1997. }
  1998. [Test]
  1999. public void DeserializeRequiredMembersClassWithNullValues()
  2000. {
  2001. string json = @"{
  2002. ""FirstName"": ""I can't be null bro!"",
  2003. ""MiddleName"": null,
  2004. ""LastName"": null,
  2005. ""BirthDate"": ""\/Date(977309755000)\/""
  2006. }";
  2007. RequiredMembersClass c = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
  2008. Assert.AreEqual("I can't be null bro!", c.FirstName);
  2009. Assert.AreEqual(null, c.MiddleName);
  2010. Assert.AreEqual(null, c.LastName);
  2011. }
  2012. [Test]
  2013. public void DeserializeRequiredMembersClassNullRequiredValueProperty()
  2014. {
  2015. try
  2016. {
  2017. string json = @"{
  2018. ""FirstName"": null,
  2019. ""MiddleName"": null,
  2020. ""LastName"": null,
  2021. ""BirthDate"": ""\/Date(977309755000)\/""
  2022. }";
  2023. JsonConvert.DeserializeObject<RequiredMembersClass>(json);
  2024. Assert.Fail();
  2025. }
  2026. catch (JsonSerializationException ex)
  2027. {
  2028. Assert.IsTrue(ex.Message.StartsWith("Required property 'FirstName' expects a value but got null. Path ''"));
  2029. }
  2030. }
  2031. [Test]
  2032. public void SerializeRequiredMembersClassNullRequiredValueProperty()
  2033. {
  2034. ExceptionAssert.Throws<JsonSerializationException>(
  2035. "Cannot write a null value for property 'FirstName'. Property requires a value. Path ''.",
  2036. () =>
  2037. {
  2038. RequiredMembersClass requiredMembersClass = new RequiredMembersClass
  2039. {
  2040. FirstName = null,
  2041. BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc),
  2042. LastName = null,
  2043. MiddleName = null
  2044. };
  2045. string json = JsonConvert.SerializeObject(requiredMembersClass);
  2046. Console.WriteLine(json);
  2047. });
  2048. }
  2049. [Test]
  2050. public void RequiredMembersClassMissingRequiredProperty()
  2051. {
  2052. try
  2053. {
  2054. string json = @"{
  2055. ""FirstName"": ""Bob""
  2056. }";
  2057. JsonConvert.DeserializeObject<RequiredMembersClass>(json);
  2058. Assert.Fail();
  2059. }
  2060. catch (JsonSerializationException ex)
  2061. {
  2062. Assert.IsTrue(ex.Message.StartsWith("Required property 'LastName' not found in JSON. Path ''"));
  2063. }
  2064. }
  2065. [Test]
  2066. public void SerializeJaggedArray()
  2067. {
  2068. JaggedArray aa = new JaggedArray();
  2069. aa.Before = "Before!";
  2070. aa.After = "After!";
  2071. aa.Coordinates = new[] { new[] { 1, 1 }, new[] { 1, 2 }, new[] { 2, 1 }, new[] { 2, 2 } };
  2072. string json = JsonConvert.SerializeObject(aa);
  2073. Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json);
  2074. }
  2075. [Test]
  2076. public void DeserializeJaggedArray()
  2077. {
  2078. string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}";
  2079. JaggedArray aa = JsonConvert.DeserializeObject<JaggedArray>(json);
  2080. Assert.AreEqual("Before!", aa.Before);
  2081. Assert.AreEqual("After!", aa.After);
  2082. Assert.AreEqual(4, aa.Coordinates.Length);
  2083. Assert.AreEqual(2, aa.Coordinates[0].Length);
  2084. Assert.AreEqual(1, aa.Coordinates[0][0]);
  2085. Assert.AreEqual(2, aa.Coordinates[1][1]);
  2086. string after = JsonConvert.SerializeObject(aa);
  2087. Assert.AreEqual(json, after);
  2088. }
  2089. [Test]
  2090. public void DeserializeGoogleGeoCode()
  2091. {
  2092. string json = @"{
  2093. ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"",
  2094. ""Status"": {
  2095. ""code"": 200,
  2096. ""request"": ""geocode""
  2097. },
  2098. ""Placemark"": [
  2099. {
  2100. ""address"": ""1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"",
  2101. ""AddressDetails"": {
  2102. ""Country"": {
  2103. ""CountryNameCode"": ""US"",
  2104. ""AdministrativeArea"": {
  2105. ""AdministrativeAreaName"": ""CA"",
  2106. ""SubAdministrativeArea"": {
  2107. ""SubAdministrativeAreaName"": ""Santa Clara"",
  2108. ""Locality"": {
  2109. ""LocalityName"": ""Mountain View"",
  2110. ""Thoroughfare"": {
  2111. ""ThoroughfareName"": ""1600 Amphitheatre Pkwy""
  2112. },
  2113. ""PostalCode"": {
  2114. ""PostalCodeNumber"": ""94043""
  2115. }
  2116. }
  2117. }
  2118. }
  2119. },
  2120. ""Accuracy"": 8
  2121. },
  2122. ""Point"": {
  2123. ""coordinates"": [-122.083739, 37.423021, 0]
  2124. }
  2125. }
  2126. ]
  2127. }";
  2128. GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject<GoogleMapGeocoderStructure>(json);
  2129. }
  2130. [Test]
  2131. public void DeserializeInterfaceProperty()
  2132. {
  2133. InterfacePropertyTestClass testClass = new InterfacePropertyTestClass();
  2134. testClass.co = new Co();
  2135. String strFromTest = JsonConvert.SerializeObject(testClass);
  2136. ExceptionAssert.Throws<JsonSerializationException>(
  2137. @"Could not create an instance of type Newtonsoft.Json.Tests.TestObjects.ICo. Type is an interface or abstract class and cannot be instantiated. Path 'co.Name', line 1, position 14.",
  2138. () => { InterfacePropertyTestClass testFromDe = (InterfacePropertyTestClass)JsonConvert.DeserializeObject(strFromTest, typeof(InterfacePropertyTestClass)); });
  2139. }
  2140. private Person GetPerson()
  2141. {
  2142. Person person = new Person
  2143. {
  2144. Name = "Mike Manager",
  2145. BirthDate = new DateTime(1983, 8, 3, 0, 0, 0, DateTimeKind.Utc),
  2146. Department = "IT",
  2147. LastModified = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)
  2148. };
  2149. return person;
  2150. }
  2151. [Test]
  2152. public void WriteJsonDates()
  2153. {
  2154. LogEntry entry = new LogEntry
  2155. {
  2156. LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
  2157. Details = "Application started."
  2158. };
  2159. string defaultJson = JsonConvert.SerializeObject(entry);
  2160. // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
  2161. string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());
  2162. // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00.0000000Z"}
  2163. string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
  2164. // {"Details":"Application started.","LogDate":new Date(1234656000000)}
  2165. Console.WriteLine(defaultJson);
  2166. Console.WriteLine(isoJson);
  2167. Console.WriteLine(javascriptJson);
  2168. }
  2169. public void GenericListAndDictionaryInterfaceProperties()
  2170. {
  2171. GenericListAndDictionaryInterfaceProperties o = new GenericListAndDictionaryInterfaceProperties();
  2172. o.IDictionaryProperty = new Dictionary<string, int>
  2173. {
  2174. { "one", 1 },
  2175. { "two", 2 },
  2176. { "three", 3 }
  2177. };
  2178. o.IListProperty = new List<int>
  2179. {
  2180. 1, 2, 3
  2181. };
  2182. o.IEnumerableProperty = new List<int>
  2183. {
  2184. 4, 5, 6
  2185. };
  2186. string json = JsonConvert.SerializeObject(o, Formatting.Indented);
  2187. Assert.AreEqual(@"{
  2188. ""IEnumerableProperty"": [
  2189. 4,
  2190. 5,
  2191. 6
  2192. ],
  2193. ""IListProperty"": [
  2194. 1,
  2195. 2,
  2196. 3
  2197. ],
  2198. ""IDictionaryProperty"": {
  2199. ""one"": 1,
  2200. ""two"": 2,
  2201. ""three"": 3
  2202. }
  2203. }", json);
  2204. GenericListAndDictionaryInterfaceProperties deserializedObject = JsonConvert.DeserializeObject<GenericListAndDictionaryInterfaceProperties>(json);
  2205. Assert.IsNotNull(deserializedObject);
  2206. CollectionAssert.AreEqual(o.IListProperty.ToArray(), deserializedObject.IListProperty.ToArray());
  2207. CollectionAssert.AreEqual(o.IEnumerableProperty.ToArray(), deserializedObject.IEnumerableProperty.ToArray());
  2208. CollectionAssert.AreEqual(o.IDictionaryProperty.ToArray(), deserializedObject.IDictionaryProperty.ToArray());
  2209. }
  2210. [Test]
  2211. public void DeserializeBestMatchPropertyCase()
  2212. {
  2213. string json = @"{
  2214. ""firstName"": ""firstName"",
  2215. ""FirstName"": ""FirstName"",
  2216. ""LastName"": ""LastName"",
  2217. ""lastName"": ""lastName"",
  2218. }";
  2219. PropertyCase o = JsonConvert.DeserializeObject<PropertyCase>(json);
  2220. Assert.IsNotNull(o);
  2221. Assert.AreEqual("firstName", o.firstName);
  2222. Assert.AreEqual("FirstName", o.FirstName);
  2223. Assert.AreEqual("LastName", o.LastName);
  2224. Assert.AreEqual("lastName", o.lastName);
  2225. }
  2226. public sealed class ConstructorAndDefaultValueAttributeTestClass
  2227. {
  2228. public ConstructorAndDefaultValueAttributeTestClass(string testProperty1)
  2229. {
  2230. TestProperty1 = testProperty1;
  2231. }
  2232. public string TestProperty1 { get; set; }
  2233. [DefaultValue(21)]
  2234. public int TestProperty2 { get; set; }
  2235. }
  2236. [Test]
  2237. public void PopulateDefaultValueWhenUsingConstructor()
  2238. {
  2239. string json = "{ 'testProperty1': 'value' }";
  2240. ConstructorAndDefaultValueAttributeTestClass c = JsonConvert.DeserializeObject<ConstructorAndDefaultValueAttributeTestClass>(json, new JsonSerializerSettings
  2241. {
  2242. DefaultValueHandling = DefaultValueHandling.Populate
  2243. });
  2244. Assert.AreEqual("value", c.TestProperty1);
  2245. Assert.AreEqual(21, c.TestProperty2);
  2246. c = JsonConvert.DeserializeObject<ConstructorAndDefaultValueAttributeTestClass>(json, new JsonSerializerSettings
  2247. {
  2248. DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate
  2249. });
  2250. Assert.AreEqual("value", c.TestProperty1);
  2251. Assert.AreEqual(21, c.TestProperty2);
  2252. }
  2253. public sealed class ConstructorAndRequiredTestClass
  2254. {
  2255. public ConstructorAndRequiredTestClass(string testProperty1)
  2256. {
  2257. TestProperty1 = testProperty1;
  2258. }
  2259. public string TestProperty1 { get; set; }
  2260. [JsonProperty(Required = Required.AllowNull)]
  2261. public int TestProperty2 { get; set; }
  2262. }
  2263. [Test]
  2264. public void RequiredWhenUsingConstructor()
  2265. {
  2266. try
  2267. {
  2268. string json = "{ 'testProperty1': 'value' }";
  2269. JsonConvert.DeserializeObject<ConstructorAndRequiredTestClass>(json);
  2270. Assert.Fail();
  2271. }
  2272. catch (JsonSerializationException ex)
  2273. {
  2274. Assert.IsTrue(ex.Message.StartsWith("Required property 'TestProperty2' not found in JSON. Path ''"));
  2275. }
  2276. }
  2277. [Test]
  2278. public void DeserializePropertiesOnToNonDefaultConstructor()
  2279. {
  2280. SubKlass i = new SubKlass("my subprop");
  2281. i.SuperProp = "overrided superprop";
  2282. string json = JsonConvert.SerializeObject(i);
  2283. Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json);
  2284. SubKlass ii = JsonConvert.DeserializeObject<SubKlass>(json);
  2285. string newJson = JsonConvert.SerializeObject(ii);
  2286. Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson);
  2287. }
  2288. [Test]
  2289. public void DeserializePropertiesOnToNonDefaultConstructorWithReferenceTracking()
  2290. {
  2291. SubKlass i = new SubKlass("my subprop");
  2292. i.SuperProp = "overrided superprop";
  2293. string json = JsonConvert.SerializeObject(i, new JsonSerializerSettings
  2294. {
  2295. PreserveReferencesHandling = PreserveReferencesHandling.Objects
  2296. });
  2297. Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json);
  2298. SubKlass ii = JsonConvert.DeserializeObject<SubKlass>(json, new JsonSerializerSettings
  2299. {
  2300. PreserveReferencesHandling = PreserveReferencesHandling.Objects
  2301. });
  2302. string newJson = JsonConvert.SerializeObject(ii, new JsonSerializerSettings
  2303. {
  2304. PreserveReferencesHandling = PreserveReferencesHandling.Objects
  2305. });
  2306. Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson);
  2307. }
  2308. [Test]
  2309. public void SerializeJsonPropertyWithHandlingValues()
  2310. {
  2311. JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
  2312. o.DefaultValueHandlingIgnoreProperty = "Default!";
  2313. o.DefaultValueHandlingIncludeProperty = "Default!";
  2314. o.DefaultValueHandlingPopulateProperty = "Default!";
  2315. o.DefaultValueHandlingIgnoreAndPopulateProperty = "Default!";
  2316. string json = JsonConvert.SerializeObject(o, Formatting.Indented);
  2317. Assert.AreEqual(@"{
  2318. ""DefaultValueHandlingIncludeProperty"": ""Default!"",
  2319. ""DefaultValueHandlingPopulateProperty"": ""Default!"",
  2320. ""NullValueHandlingIncludeProperty"": null,
  2321. ""ReferenceLoopHandlingErrorProperty"": null,
  2322. ""ReferenceLoopHandlingIgnoreProperty"": null,
  2323. ""ReferenceLoopHandlingSerializeProperty"": null
  2324. }", json);
  2325. json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
  2326. Assert.AreEqual(@"{
  2327. ""DefaultValueHandlingIncludeProperty"": ""Default!"",
  2328. ""DefaultValueHandlingPopulateProperty"": ""Default!"",
  2329. ""NullValueHandlingIncludeProperty"": null
  2330. }", json);
  2331. }
  2332. [Test]
  2333. public void DeserializeJsonPropertyWithHandlingValues()
  2334. {
  2335. string json = "{}";
  2336. JsonPropertyWithHandlingValues o = JsonConvert.DeserializeObject<JsonPropertyWithHandlingValues>(json);
  2337. Assert.AreEqual("Default!", o.DefaultValueHandlingIgnoreAndPopulateProperty);
  2338. Assert.AreEqual("Default!", o.DefaultValueHandlingPopulateProperty);
  2339. Assert.AreEqual(null, o.DefaultValueHandlingIgnoreProperty);
  2340. Assert.AreEqual(null, o.DefaultValueHandlingIncludeProperty);
  2341. }
  2342. [Test]
  2343. public void JsonPropertyWithHandlingValues_ReferenceLoopError()
  2344. {
  2345. string classRef = typeof(JsonPropertyWithHandlingValues).FullName;
  2346. ExceptionAssert.Throws<JsonSerializationException>(
  2347. "Self referencing loop detected for property 'ReferenceLoopHandlingErrorProperty' with type '" + classRef + "'. Path ''.",
  2348. () =>
  2349. {
  2350. JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
  2351. o.ReferenceLoopHandlingErrorProperty = o;
  2352. JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
  2353. });
  2354. }
  2355. [Test]
  2356. public void PartialClassDeserialize()
  2357. {
  2358. string json = @"{
  2359. ""request"": ""ux.settings.update"",
  2360. ""sid"": ""14c561bd-32a8-457e-b4e5-4bba0832897f"",
  2361. ""uid"": ""30c39065-0f31-de11-9442-001e3786a8ec"",
  2362. ""fidOrder"": [
  2363. ""id"",
  2364. ""andytest_name"",
  2365. ""andytest_age"",
  2366. ""andytest_address"",
  2367. ""andytest_phone"",
  2368. ""date"",
  2369. ""title"",
  2370. ""titleId""
  2371. ],
  2372. ""entityName"": ""Andy Test"",
  2373. ""setting"": ""entity.field.order""
  2374. }";
  2375. RequestOnly r = JsonConvert.DeserializeObject<RequestOnly>(json);
  2376. Assert.AreEqual("ux.settings.update", r.Request);
  2377. NonRequest n = JsonConvert.DeserializeObject<NonRequest>(json);
  2378. Assert.AreEqual(new Guid("14c561bd-32a8-457e-b4e5-4bba0832897f"), n.Sid);
  2379. Assert.AreEqual(new Guid("30c39065-0f31-de11-9442-001e3786a8ec"), n.Uid);
  2380. Assert.AreEqual(8, n.FidOrder.Count);
  2381. Assert.AreEqual("id", n.FidOrder[0]);
  2382. Assert.AreEqual("titleId", n.FidOrder[n.FidOrder.Count - 1]);
  2383. }
  2384. #if !(NET20 || NETFX_CORE || PORTABLE || PORTABLE40)
  2385. [MetadataType(typeof(OptInClassMetadata))]
  2386. public class OptInClass
  2387. {
  2388. [DataContract]
  2389. public class OptInClassMetadata
  2390. {
  2391. [DataMember]
  2392. public string Name { get; set; }
  2393. [DataMember]
  2394. public int Age { get; set; }
  2395. public string NotIncluded { get; set; }
  2396. }
  2397. public string Name { get; set; }
  2398. public int Age { get; set; }
  2399. public string NotIncluded { get; set; }
  2400. }
  2401. [Test]
  2402. public void OptInClassMetadataSerialization()
  2403. {
  2404. OptInClass optInClass = new OptInClass();
  2405. optInClass.Age = 26;
  2406. optInClass.Name = "James NK";
  2407. optInClass.NotIncluded = "Poor me :(";
  2408. string json = JsonConvert.SerializeObject(optInClass, Formatting.Indented);
  2409. Assert.AreEqual(@"{
  2410. ""Name"": ""James NK"",
  2411. ""Age"": 26
  2412. }", json);
  2413. OptInClass newOptInClass = JsonConvert.DeserializeObject<OptInClass>(@"{
  2414. ""Name"": ""James NK"",
  2415. ""NotIncluded"": ""Ignore me!"",
  2416. ""Age"": 26
  2417. }");
  2418. Assert.AreEqual(26, newOptInClass.Age);
  2419. Assert.AreEqual("James NK", newOptInClass.Name);
  2420. Assert.AreEqual(null, newOptInClass.NotIncluded);
  2421. }
  2422. #endif
  2423. #if !NET20
  2424. [DataContract]
  2425. public class DataContractPrivateMembers
  2426. {
  2427. public DataContractPrivateMembers()
  2428. {
  2429. }
  2430. public DataContractPrivateMembers(string name, int age, int rank, string title)
  2431. {
  2432. _name = name;
  2433. Age = age;
  2434. Rank = rank;
  2435. Title = title;
  2436. }
  2437. [DataMember]
  2438. private string _name;
  2439. [DataMember(Name = "_age")]
  2440. private int Age { get; set; }
  2441. [JsonProperty]
  2442. private int Rank { get; set; }
  2443. [JsonProperty(PropertyName = "JsonTitle")]
  2444. [DataMember(Name = "DataTitle")]
  2445. private string Title { get; set; }
  2446. public string NotIncluded { get; set; }
  2447. public override string ToString()
  2448. {
  2449. return "_name: " + _name + ", _age: " + Age + ", Rank: " + Rank + ", JsonTitle: " + Title;
  2450. }
  2451. }
  2452. [Test]
  2453. public void SerializeDataContractPrivateMembers()
  2454. {
  2455. DataContractPrivateMembers c = new DataContractPrivateMembers("Jeff", 26, 10, "Dr");
  2456. c.NotIncluded = "Hi";
  2457. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  2458. Assert.AreEqual(@"{
  2459. ""_name"": ""Jeff"",
  2460. ""_age"": 26,
  2461. ""Rank"": 10,
  2462. ""JsonTitle"": ""Dr""
  2463. }", json);
  2464. DataContractPrivateMembers cc = JsonConvert.DeserializeObject<DataContractPrivateMembers>(json);
  2465. Assert.AreEqual("_name: Jeff, _age: 26, Rank: 10, JsonTitle: Dr", cc.ToString());
  2466. }
  2467. #endif
  2468. [Test]
  2469. public void DeserializeDictionaryInterface()
  2470. {
  2471. string json = @"{
  2472. ""Name"": ""Name!"",
  2473. ""Dictionary"": {
  2474. ""Item"": 11
  2475. }
  2476. }";
  2477. DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(
  2478. json,
  2479. new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace });
  2480. Assert.AreEqual("Name!", c.Name);
  2481. Assert.AreEqual(1, c.Dictionary.Count);
  2482. Assert.AreEqual(11, c.Dictionary["Item"]);
  2483. }
  2484. [Test]
  2485. public void DeserializeDictionaryInterfaceWithExistingValues()
  2486. {
  2487. string json = @"{
  2488. ""Random"": {
  2489. ""blah"": 1
  2490. },
  2491. ""Name"": ""Name!"",
  2492. ""Dictionary"": {
  2493. ""Item"": 11,
  2494. ""Item1"": 12
  2495. },
  2496. ""Collection"": [
  2497. 999
  2498. ],
  2499. ""Employee"": {
  2500. ""Manager"": {
  2501. ""Name"": ""ManagerName!""
  2502. }
  2503. }
  2504. }";
  2505. DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
  2506. new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Reuse });
  2507. Assert.AreEqual("Name!", c.Name);
  2508. Assert.AreEqual(3, c.Dictionary.Count);
  2509. Assert.AreEqual(11, c.Dictionary["Item"]);
  2510. Assert.AreEqual(1, c.Dictionary["existing"]);
  2511. Assert.AreEqual(4, c.Collection.Count);
  2512. Assert.AreEqual(1, c.Collection.ElementAt(0));
  2513. Assert.AreEqual(999, c.Collection.ElementAt(3));
  2514. Assert.AreEqual("EmployeeName!", c.Employee.Name);
  2515. Assert.AreEqual("ManagerName!", c.Employee.Manager.Name);
  2516. Assert.IsNotNull(c.Random);
  2517. }
  2518. [Test]
  2519. public void TypedObjectDeserializationWithComments()
  2520. {
  2521. string json = @"/*comment1*/ { /*comment2*/
  2522. ""Name"": /*comment3*/ ""Apple"" /*comment4*/, /*comment5*/
  2523. ""ExpiryDate"": ""\/Date(1230422400000)\/"",
  2524. ""Price"": 3.99,
  2525. ""Sizes"": /*comment6*/ [ /*comment7*/
  2526. ""Small"", /*comment8*/
  2527. ""Medium"" /*comment9*/,
  2528. /*comment10*/ ""Large""
  2529. /*comment11*/ ] /*comment12*/
  2530. } /*comment13*/";
  2531. Product deserializedProduct = (Product)JsonConvert.DeserializeObject(json, typeof(Product));
  2532. Assert.AreEqual("Apple", deserializedProduct.Name);
  2533. Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate);
  2534. Assert.AreEqual(3.99m, deserializedProduct.Price);
  2535. Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
  2536. Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
  2537. Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
  2538. }
  2539. [Test]
  2540. public void NestedInsideOuterObject()
  2541. {
  2542. string json = @"{
  2543. ""short"": {
  2544. ""original"": ""http://www.contrast.ie/blog/online&#45;marketing&#45;2009/"",
  2545. ""short"": ""m2sqc6"",
  2546. ""shortened"": ""http://short.ie/m2sqc6"",
  2547. ""error"": {
  2548. ""code"": 0,
  2549. ""msg"": ""No action taken""
  2550. }
  2551. }
  2552. }";
  2553. JObject o = JObject.Parse(json);
  2554. Shortie s = JsonConvert.DeserializeObject<Shortie>(o["short"].ToString());
  2555. Assert.IsNotNull(s);
  2556. Assert.AreEqual(s.Original, "http://www.contrast.ie/blog/online&#45;marketing&#45;2009/");
  2557. Assert.AreEqual(s.Short, "m2sqc6");
  2558. Assert.AreEqual(s.Shortened, "http://short.ie/m2sqc6");
  2559. }
  2560. [Test]
  2561. public void UriSerialization()
  2562. {
  2563. Uri uri = new Uri("http://codeplex.com");
  2564. string json = JsonConvert.SerializeObject(uri);
  2565. Assert.AreEqual("http://codeplex.com/", uri.ToString());
  2566. Uri newUri = JsonConvert.DeserializeObject<Uri>(json);
  2567. Assert.AreEqual(uri, newUri);
  2568. }
  2569. [Test]
  2570. public void AnonymousPlusLinqToSql()
  2571. {
  2572. var value = new
  2573. {
  2574. bar = new JObject(new JProperty("baz", 13))
  2575. };
  2576. string json = JsonConvert.SerializeObject(value);
  2577. Assert.AreEqual(@"{""bar"":{""baz"":13}}", json);
  2578. }
  2579. [Test]
  2580. public void SerializeEnumerableAsObject()
  2581. {
  2582. Content content = new Content
  2583. {
  2584. Text = "Blah, blah, blah",
  2585. Children = new List<Content>
  2586. {
  2587. new Content { Text = "First" },
  2588. new Content { Text = "Second" }
  2589. }
  2590. };
  2591. string json = JsonConvert.SerializeObject(content, Formatting.Indented);
  2592. Assert.AreEqual(@"{
  2593. ""Children"": [
  2594. {
  2595. ""Children"": null,
  2596. ""Text"": ""First""
  2597. },
  2598. {
  2599. ""Children"": null,
  2600. ""Text"": ""Second""
  2601. }
  2602. ],
  2603. ""Text"": ""Blah, blah, blah""
  2604. }", json);
  2605. }
  2606. [Test]
  2607. public void DeserializeEnumerableAsObject()
  2608. {
  2609. string json = @"{
  2610. ""Children"": [
  2611. {
  2612. ""Children"": null,
  2613. ""Text"": ""First""
  2614. },
  2615. {
  2616. ""Children"": null,
  2617. ""Text"": ""Second""
  2618. }
  2619. ],
  2620. ""Text"": ""Blah, blah, blah""
  2621. }";
  2622. Content content = JsonConvert.DeserializeObject<Content>(json);
  2623. Assert.AreEqual("Blah, blah, blah", content.Text);
  2624. Assert.AreEqual(2, content.Children.Count);
  2625. Assert.AreEqual("First", content.Children[0].Text);
  2626. Assert.AreEqual("Second", content.Children[1].Text);
  2627. }
  2628. [Test]
  2629. public void RoleTransferTest()
  2630. {
  2631. string json = @"{""Operation"":""1"",""RoleName"":""Admin"",""Direction"":""0""}";
  2632. RoleTransfer r = JsonConvert.DeserializeObject<RoleTransfer>(json);
  2633. Assert.AreEqual(RoleTransferOperation.Second, r.Operation);
  2634. Assert.AreEqual("Admin", r.RoleName);
  2635. Assert.AreEqual(RoleTransferDirection.First, r.Direction);
  2636. }
  2637. [Test]
  2638. public void PrimitiveValuesInObjectArray()
  2639. {
  2640. string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}";
  2641. ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
  2642. Assert.AreEqual("Router", o.Action);
  2643. Assert.AreEqual("Navigate", o.Method);
  2644. Assert.AreEqual(2, o.Data.Length);
  2645. Assert.AreEqual("dashboard", o.Data[0]);
  2646. Assert.AreEqual(null, o.Data[1]);
  2647. }
  2648. [Test]
  2649. public void ComplexValuesInObjectArray()
  2650. {
  2651. string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}";
  2652. ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
  2653. Assert.AreEqual("Router", o.Action);
  2654. Assert.AreEqual("Navigate", o.Method);
  2655. Assert.AreEqual(3, o.Data.Length);
  2656. Assert.AreEqual("dashboard", o.Data[0]);
  2657. CustomAssert.IsInstanceOfType(typeof(JArray), o.Data[1]);
  2658. Assert.AreEqual(4, ((JArray)o.Data[1]).Count);
  2659. CustomAssert.IsInstanceOfType(typeof(JObject), o.Data[2]);
  2660. Assert.AreEqual(1, ((JObject)o.Data[2]).Count);
  2661. Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]);
  2662. }
  2663. [Test]
  2664. public void DeserializeGenericDictionary()
  2665. {
  2666. string json = @"{""key1"":""value1"",""key2"":""value2""}";
  2667. Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  2668. Console.WriteLine(values.Count);
  2669. // 2
  2670. Console.WriteLine(values["key1"]);
  2671. // value1
  2672. Assert.AreEqual(2, values.Count);
  2673. Assert.AreEqual("value1", values["key1"]);
  2674. Assert.AreEqual("value2", values["key2"]);
  2675. }
  2676. [Test]
  2677. public void SerializeGenericList()
  2678. {
  2679. Product p1 = new Product
  2680. {
  2681. Name = "Product 1",
  2682. Price = 99.95m,
  2683. ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc),
  2684. };
  2685. Product p2 = new Product
  2686. {
  2687. Name = "Product 2",
  2688. Price = 12.50m,
  2689. ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc),
  2690. };
  2691. List<Product> products = new List<Product>();
  2692. products.Add(p1);
  2693. products.Add(p2);
  2694. string json = JsonConvert.SerializeObject(products, Formatting.Indented);
  2695. //[
  2696. // {
  2697. // "Name": "Product 1",
  2698. // "ExpiryDate": "\/Date(978048000000)\/",
  2699. // "Price": 99.95,
  2700. // "Sizes": null
  2701. // },
  2702. // {
  2703. // "Name": "Product 2",
  2704. // "ExpiryDate": "\/Date(1248998400000)\/",
  2705. // "Price": 12.50,
  2706. // "Sizes": null
  2707. // }
  2708. //]
  2709. Assert.AreEqual(@"[
  2710. {
  2711. ""Name"": ""Product 1"",
  2712. ""ExpiryDate"": ""2000-12-29T00:00:00Z"",
  2713. ""Price"": 99.95,
  2714. ""Sizes"": null
  2715. },
  2716. {
  2717. ""Name"": ""Product 2"",
  2718. ""ExpiryDate"": ""2009-07-31T00:00:00Z"",
  2719. ""Price"": 12.50,
  2720. ""Sizes"": null
  2721. }
  2722. ]", json);
  2723. }
  2724. [Test]
  2725. public void DeserializeGenericList()
  2726. {
  2727. string json = @"[
  2728. {
  2729. ""Name"": ""Product 1"",
  2730. ""ExpiryDate"": ""\/Date(978048000000)\/"",
  2731. ""Price"": 99.95,
  2732. ""Sizes"": null
  2733. },
  2734. {
  2735. ""Name"": ""Product 2"",
  2736. ""ExpiryDate"": ""\/Date(1248998400000)\/"",
  2737. ""Price"": 12.50,
  2738. ""Sizes"": null
  2739. }
  2740. ]";
  2741. List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
  2742. Console.WriteLine(products.Count);
  2743. // 2
  2744. Product p1 = products[0];
  2745. Console.WriteLine(p1.Name);
  2746. // Product 1
  2747. Assert.AreEqual(2, products.Count);
  2748. Assert.AreEqual("Product 1", products[0].Name);
  2749. }
  2750. #if !NET20
  2751. [Test]
  2752. public void DeserializeEmptyStringToNullableDateTime()
  2753. {
  2754. string json = @"{""DateTimeField"":""""}";
  2755. NullableDateTimeTestClass c = JsonConvert.DeserializeObject<NullableDateTimeTestClass>(json);
  2756. Assert.AreEqual(null, c.DateTimeField);
  2757. }
  2758. #endif
  2759. [Test]
  2760. public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments()
  2761. {
  2762. 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)\/""}";
  2763. ExceptionAssert.Throws<JsonSerializationException>(
  2764. @"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. Path 'sublocation', line 1, position 15.",
  2765. () => { JsonConvert.DeserializeObject<TestObjects.Event>(json); });
  2766. }
  2767. [Test]
  2768. public void DeserializeObjectSetOnlyProperty()
  2769. {
  2770. string json = @"{'SetOnlyProperty':[1,2,3,4,5]}";
  2771. SetOnlyPropertyClass2 setOnly = JsonConvert.DeserializeObject<SetOnlyPropertyClass2>(json);
  2772. JArray a = (JArray)setOnly.GetValue();
  2773. Assert.AreEqual(5, a.Count);
  2774. Assert.AreEqual(1, (int)a[0]);
  2775. Assert.AreEqual(5, (int)a[a.Count - 1]);
  2776. }
  2777. [Test]
  2778. public void DeserializeOptInClasses()
  2779. {
  2780. string json = @"{id: ""12"", name: ""test"", items: [{id: ""112"", name: ""testing""}]}";
  2781. ListTestClass l = JsonConvert.DeserializeObject<ListTestClass>(json);
  2782. }
  2783. [Test]
  2784. public void DeserializeNullableListWithNulls()
  2785. {
  2786. List<decimal?> l = JsonConvert.DeserializeObject<List<decimal?>>("[ 3.3, null, 1.1 ] ");
  2787. Assert.AreEqual(3, l.Count);
  2788. Assert.AreEqual(3.3m, l[0]);
  2789. Assert.AreEqual(null, l[1]);
  2790. Assert.AreEqual(1.1m, l[2]);
  2791. }
  2792. [Test]
  2793. public void CannotDeserializeArrayIntoObject()
  2794. {
  2795. string json = @"[]";
  2796. ExceptionAssert.Throws<JsonSerializationException>(
  2797. @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Newtonsoft.Json.Tests.TestObjects.Person' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly.
  2798. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
  2799. Path '', line 1, position 1.",
  2800. () => { JsonConvert.DeserializeObject<Person>(json); });
  2801. }
  2802. [Test]
  2803. public void CannotDeserializeArrayIntoDictionary()
  2804. {
  2805. string json = @"[]";
  2806. ExceptionAssert.Throws<JsonSerializationException>(
  2807. @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly.
  2808. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
  2809. Path '', line 1, position 1.",
  2810. () => { JsonConvert.DeserializeObject<Dictionary<string, string>>(json); });
  2811. }
  2812. #if !(NETFX_CORE || PORTABLE)
  2813. [Test]
  2814. public void CannotDeserializeArrayIntoSerializable()
  2815. {
  2816. string json = @"[]";
  2817. ExceptionAssert.Throws<JsonSerializationException>(
  2818. @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Exception' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly.
  2819. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
  2820. Path '', line 1, position 1.",
  2821. () => { JsonConvert.DeserializeObject<Exception>(json); });
  2822. }
  2823. #endif
  2824. [Test]
  2825. public void CannotDeserializeArrayIntoDouble()
  2826. {
  2827. string json = @"[]";
  2828. ExceptionAssert.Throws<JsonSerializationException>(
  2829. @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Double' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly.
  2830. To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
  2831. Path '', line 1, position 1.",
  2832. () => { JsonConvert.DeserializeObject<double>(json); });
  2833. }
  2834. #if !(NET35 || NET20 || PORTABLE40)
  2835. [Test]
  2836. public void CannotDeserializeArrayIntoDynamic()
  2837. {
  2838. string json = @"[]";
  2839. ExceptionAssert.Throws<JsonSerializationException>(
  2840. @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Newtonsoft.Json.Tests.Linq.DynamicDictionary' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly.
  2841. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
  2842. Path '', line 1, position 1.",
  2843. () => { JsonConvert.DeserializeObject<DynamicDictionary>(json); });
  2844. }
  2845. #endif
  2846. [Test]
  2847. public void CannotDeserializeArrayIntoLinqToJson()
  2848. {
  2849. string json = @"[]";
  2850. ExceptionAssert.Throws<InvalidCastException>(
  2851. @"Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'Newtonsoft.Json.Linq.JObject'.",
  2852. () => { JsonConvert.DeserializeObject<JObject>(json); });
  2853. }
  2854. [Test]
  2855. public void CannotDeserializeConstructorIntoObject()
  2856. {
  2857. string json = @"new Constructor(123)";
  2858. ExceptionAssert.Throws<JsonSerializationException>(
  2859. @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 16.",
  2860. () => { JsonConvert.DeserializeObject<Person>(json); });
  2861. }
  2862. [Test]
  2863. public void CannotDeserializeConstructorIntoObjectNested()
  2864. {
  2865. string json = @"[new Constructor(123)]";
  2866. ExceptionAssert.Throws<JsonSerializationException>(
  2867. @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '[0]', line 1, position 17.",
  2868. () => { JsonConvert.DeserializeObject<List<Person>>(json); });
  2869. }
  2870. [Test]
  2871. public void CannotDeserializeObjectIntoArray()
  2872. {
  2873. string json = @"{}";
  2874. try
  2875. {
  2876. JsonConvert.DeserializeObject<List<Person>>(json);
  2877. Assert.Fail();
  2878. }
  2879. catch (JsonSerializationException ex)
  2880. {
  2881. Assert.IsTrue(ex.Message.StartsWith(@"Cannot deserialize the current JSON object (e.g. {""name"":""value""}) into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
  2882. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
  2883. Path ''"));
  2884. }
  2885. }
  2886. [Test]
  2887. public void CannotPopulateArrayIntoObject()
  2888. {
  2889. string json = @"[]";
  2890. ExceptionAssert.Throws<JsonSerializationException>(
  2891. @"Cannot populate JSON array onto type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 1.",
  2892. () => { JsonConvert.PopulateObject(json, new Person()); });
  2893. }
  2894. [Test]
  2895. public void CannotPopulateObjectIntoArray()
  2896. {
  2897. string json = @"{}";
  2898. ExceptionAssert.Throws<JsonSerializationException>(
  2899. @"Cannot populate JSON object onto type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'. Path '', line 1, position 2.",
  2900. () => { JsonConvert.PopulateObject(json, new List<Person>()); });
  2901. }
  2902. [Test]
  2903. public void DeserializeEmptyString()
  2904. {
  2905. string json = @"{""Name"":""""}";
  2906. Person p = JsonConvert.DeserializeObject<Person>(json);
  2907. Assert.AreEqual("", p.Name);
  2908. }
  2909. [Test]
  2910. public void SerializePropertyGetError()
  2911. {
  2912. ExceptionAssert.Throws<JsonSerializationException>(
  2913. @"Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.",
  2914. () =>
  2915. {
  2916. JsonConvert.SerializeObject(new MemoryStream(), new JsonSerializerSettings
  2917. {
  2918. ContractResolver = new DefaultContractResolver
  2919. {
  2920. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  2921. IgnoreSerializableAttribute = true
  2922. #endif
  2923. }
  2924. });
  2925. });
  2926. }
  2927. [Test]
  2928. public void DeserializePropertySetError()
  2929. {
  2930. ExceptionAssert.Throws<JsonSerializationException>(
  2931. @"Error setting value to 'ReadTimeout' on 'System.IO.MemoryStream'.",
  2932. () =>
  2933. {
  2934. JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:0}", new JsonSerializerSettings
  2935. {
  2936. ContractResolver = new DefaultContractResolver
  2937. {
  2938. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  2939. IgnoreSerializableAttribute = true
  2940. #endif
  2941. }
  2942. });
  2943. });
  2944. }
  2945. [Test]
  2946. public void DeserializeEnsureTypeEmptyStringToIntError()
  2947. {
  2948. ExceptionAssert.Throws<JsonSerializationException>(
  2949. @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 15.",
  2950. () =>
  2951. {
  2952. JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:''}", new JsonSerializerSettings
  2953. {
  2954. ContractResolver = new DefaultContractResolver
  2955. {
  2956. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  2957. IgnoreSerializableAttribute = true
  2958. #endif
  2959. }
  2960. });
  2961. });
  2962. }
  2963. [Test]
  2964. public void DeserializeEnsureTypeNullToIntError()
  2965. {
  2966. ExceptionAssert.Throws<JsonSerializationException>(
  2967. @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 17.",
  2968. () =>
  2969. {
  2970. JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:null}", new JsonSerializerSettings
  2971. {
  2972. ContractResolver = new DefaultContractResolver
  2973. {
  2974. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  2975. IgnoreSerializableAttribute = true
  2976. #endif
  2977. }
  2978. });
  2979. });
  2980. }
  2981. [Test]
  2982. public void SerializeGenericListOfStrings()
  2983. {
  2984. List<String> strings = new List<String>();
  2985. strings.Add("str_1");
  2986. strings.Add("str_2");
  2987. strings.Add("str_3");
  2988. string json = JsonConvert.SerializeObject(strings);
  2989. Assert.AreEqual(@"[""str_1"",""str_2"",""str_3""]", json);
  2990. }
  2991. [Test]
  2992. public void ConstructorReadonlyFieldsTest()
  2993. {
  2994. ConstructorReadonlyFields c1 = new ConstructorReadonlyFields("String!", int.MaxValue);
  2995. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  2996. Assert.AreEqual(@"{
  2997. ""A"": ""String!"",
  2998. ""B"": 2147483647
  2999. }", json);
  3000. ConstructorReadonlyFields c2 = JsonConvert.DeserializeObject<ConstructorReadonlyFields>(json);
  3001. Assert.AreEqual("String!", c2.A);
  3002. Assert.AreEqual(int.MaxValue, c2.B);
  3003. }
  3004. [Test]
  3005. public void SerializeStruct()
  3006. {
  3007. StructTest structTest = new StructTest
  3008. {
  3009. StringProperty = "StringProperty!",
  3010. StringField = "StringField",
  3011. IntProperty = 5,
  3012. IntField = 10
  3013. };
  3014. string json = JsonConvert.SerializeObject(structTest, Formatting.Indented);
  3015. Console.WriteLine(json);
  3016. Assert.AreEqual(@"{
  3017. ""StringField"": ""StringField"",
  3018. ""IntField"": 10,
  3019. ""StringProperty"": ""StringProperty!"",
  3020. ""IntProperty"": 5
  3021. }", json);
  3022. StructTest deserialized = JsonConvert.DeserializeObject<StructTest>(json);
  3023. Assert.AreEqual(structTest.StringProperty, deserialized.StringProperty);
  3024. Assert.AreEqual(structTest.StringField, deserialized.StringField);
  3025. Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty);
  3026. Assert.AreEqual(structTest.IntField, deserialized.IntField);
  3027. }
  3028. [Test]
  3029. public void SerializeListWithJsonConverter()
  3030. {
  3031. Foo f = new Foo();
  3032. f.Bars.Add(new Bar { Id = 0 });
  3033. f.Bars.Add(new Bar { Id = 1 });
  3034. f.Bars.Add(new Bar { Id = 2 });
  3035. string json = JsonConvert.SerializeObject(f, Formatting.Indented);
  3036. Assert.AreEqual(@"{
  3037. ""Bars"": [
  3038. 0,
  3039. 1,
  3040. 2
  3041. ]
  3042. }", json);
  3043. Foo newFoo = JsonConvert.DeserializeObject<Foo>(json);
  3044. Assert.AreEqual(3, newFoo.Bars.Count);
  3045. Assert.AreEqual(0, newFoo.Bars[0].Id);
  3046. Assert.AreEqual(1, newFoo.Bars[1].Id);
  3047. Assert.AreEqual(2, newFoo.Bars[2].Id);
  3048. }
  3049. [Test]
  3050. public void SerializeGuidKeyedDictionary()
  3051. {
  3052. Dictionary<Guid, int> dictionary = new Dictionary<Guid, int>();
  3053. dictionary.Add(new Guid("F60EAEE0-AE47-488E-B330-59527B742D77"), 1);
  3054. dictionary.Add(new Guid("C2594C02-EBA1-426A-AA87-8DD8871350B0"), 2);
  3055. string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
  3056. Assert.AreEqual(@"{
  3057. ""f60eaee0-ae47-488e-b330-59527b742d77"": 1,
  3058. ""c2594c02-eba1-426a-aa87-8dd8871350b0"": 2
  3059. }", json);
  3060. }
  3061. [Test]
  3062. public void SerializePersonKeyedDictionary()
  3063. {
  3064. Dictionary<Person, int> dictionary = new Dictionary<Person, int>();
  3065. dictionary.Add(new Person { Name = "p1" }, 1);
  3066. dictionary.Add(new Person { Name = "p2" }, 2);
  3067. string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
  3068. Assert.AreEqual(@"{
  3069. ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
  3070. ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
  3071. }", json);
  3072. }
  3073. [Test]
  3074. public void DeserializePersonKeyedDictionary()
  3075. {
  3076. try
  3077. {
  3078. string json =
  3079. @"{
  3080. ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
  3081. ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
  3082. }";
  3083. JsonConvert.DeserializeObject<Dictionary<Person, int>>(json);
  3084. Assert.Fail();
  3085. }
  3086. catch (JsonSerializationException ex)
  3087. {
  3088. Assert.IsTrue(ex.Message.StartsWith("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. Path 'Newtonsoft.Json.Tests.TestObjects.Person'"));
  3089. }
  3090. }
  3091. [Test]
  3092. public void SerializeFragment()
  3093. {
  3094. string googleSearchText = @"{
  3095. ""responseData"": {
  3096. ""results"": [
  3097. {
  3098. ""GsearchResultClass"": ""GwebSearch"",
  3099. ""unescapedUrl"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
  3100. ""url"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
  3101. ""visibleUrl"": ""en.wikipedia.org"",
  3102. ""cacheUrl"": ""http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org"",
  3103. ""title"": ""<b>Paris Hilton</b> - Wikipedia, the free encyclopedia"",
  3104. ""titleNoFormatting"": ""Paris Hilton - Wikipedia, the free encyclopedia"",
  3105. ""content"": ""[1] In 2006, she released her debut album...""
  3106. },
  3107. {
  3108. ""GsearchResultClass"": ""GwebSearch"",
  3109. ""unescapedUrl"": ""http://www.imdb.com/name/nm0385296/"",
  3110. ""url"": ""http://www.imdb.com/name/nm0385296/"",
  3111. ""visibleUrl"": ""www.imdb.com"",
  3112. ""cacheUrl"": ""http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com"",
  3113. ""title"": ""<b>Paris Hilton</b>"",
  3114. ""titleNoFormatting"": ""Paris Hilton"",
  3115. ""content"": ""Self: Zoolander. Socialite <b>Paris Hilton</b>...""
  3116. }
  3117. ],
  3118. ""cursor"": {
  3119. ""pages"": [
  3120. {
  3121. ""start"": ""0"",
  3122. ""label"": 1
  3123. },
  3124. {
  3125. ""start"": ""4"",
  3126. ""label"": 2
  3127. },
  3128. {
  3129. ""start"": ""8"",
  3130. ""label"": 3
  3131. },
  3132. {
  3133. ""start"": ""12"",
  3134. ""label"": 4
  3135. }
  3136. ],
  3137. ""estimatedResultCount"": ""59600000"",
  3138. ""currentPageIndex"": 0,
  3139. ""moreResultsUrl"": ""http://www.google.com/search?oe=utf8&ie=utf8...""
  3140. }
  3141. },
  3142. ""responseDetails"": null,
  3143. ""responseStatus"": 200
  3144. }";
  3145. JObject googleSearch = JObject.Parse(googleSearchText);
  3146. // get JSON result objects into a list
  3147. IList<JToken> results = googleSearch["responseData"]["results"].Children().ToList();
  3148. // serialize JSON results into .NET objects
  3149. IList<SearchResult> searchResults = new List<SearchResult>();
  3150. foreach (JToken result in results)
  3151. {
  3152. SearchResult searchResult = JsonConvert.DeserializeObject<SearchResult>(result.ToString());
  3153. searchResults.Add(searchResult);
  3154. }
  3155. // Title = <b>Paris Hilton</b> - Wikipedia, the free encyclopedia
  3156. // Content = [1] In 2006, she released her debut album...
  3157. // Url = http://en.wikipedia.org/wiki/Paris_Hilton
  3158. // Title = <b>Paris Hilton</b>
  3159. // Content = Self: Zoolander. Socialite <b>Paris Hilton</b>...
  3160. // Url = http://www.imdb.com/name/nm0385296/
  3161. Assert.AreEqual(2, searchResults.Count);
  3162. Assert.AreEqual("<b>Paris Hilton</b> - Wikipedia, the free encyclopedia", searchResults[0].Title);
  3163. Assert.AreEqual("<b>Paris Hilton</b>", searchResults[1].Title);
  3164. }
  3165. [Test]
  3166. public void DeserializeBaseReferenceWithDerivedValue()
  3167. {
  3168. PersonPropertyClass personPropertyClass = new PersonPropertyClass();
  3169. WagePerson wagePerson = (WagePerson)personPropertyClass.Person;
  3170. wagePerson.BirthDate = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
  3171. wagePerson.Department = "McDees";
  3172. wagePerson.HourlyWage = 12.50m;
  3173. wagePerson.LastModified = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
  3174. wagePerson.Name = "Jim Bob";
  3175. string json = JsonConvert.SerializeObject(personPropertyClass, Formatting.Indented);
  3176. Assert.AreEqual(
  3177. @"{
  3178. ""Person"": {
  3179. ""HourlyWage"": 12.50,
  3180. ""Name"": ""Jim Bob"",
  3181. ""BirthDate"": ""2000-11-29T23:59:59Z"",
  3182. ""LastModified"": ""2000-11-29T23:59:59Z""
  3183. }
  3184. }",
  3185. json);
  3186. PersonPropertyClass newPersonPropertyClass = JsonConvert.DeserializeObject<PersonPropertyClass>(json);
  3187. Assert.AreEqual(wagePerson.HourlyWage, ((WagePerson)newPersonPropertyClass.Person).HourlyWage);
  3188. }
  3189. public class ExistingValueClass
  3190. {
  3191. public Dictionary<string, string> Dictionary { get; set; }
  3192. public List<string> List { get; set; }
  3193. public ExistingValueClass()
  3194. {
  3195. Dictionary = new Dictionary<string, string>
  3196. {
  3197. { "existing", "yup" }
  3198. };
  3199. List = new List<string>
  3200. {
  3201. "existing"
  3202. };
  3203. }
  3204. }
  3205. [Test]
  3206. public void DeserializePopulateDictionaryAndList()
  3207. {
  3208. ExistingValueClass d = JsonConvert.DeserializeObject<ExistingValueClass>(@"{'Dictionary':{appended:'appended',existing:'new'}}");
  3209. Assert.IsNotNull(d);
  3210. Assert.IsNotNull(d.Dictionary);
  3211. Assert.AreEqual(typeof(Dictionary<string, string>), d.Dictionary.GetType());
  3212. Assert.AreEqual(typeof(List<string>), d.List.GetType());
  3213. Assert.AreEqual(2, d.Dictionary.Count);
  3214. Assert.AreEqual("new", d.Dictionary["existing"]);
  3215. Assert.AreEqual("appended", d.Dictionary["appended"]);
  3216. Assert.AreEqual(1, d.List.Count);
  3217. Assert.AreEqual("existing", d.List[0]);
  3218. }
  3219. public interface IKeyValueId
  3220. {
  3221. int Id { get; set; }
  3222. string Key { get; set; }
  3223. string Value { get; set; }
  3224. }
  3225. public class KeyValueId : IKeyValueId
  3226. {
  3227. public int Id { get; set; }
  3228. public string Key { get; set; }
  3229. public string Value { get; set; }
  3230. }
  3231. public class ThisGenericTest<T> where T : IKeyValueId
  3232. {
  3233. private Dictionary<string, T> _dict1 = new Dictionary<string, T>();
  3234. public string MyProperty { get; set; }
  3235. public void Add(T item)
  3236. {
  3237. _dict1.Add(item.Key, item);
  3238. }
  3239. public T this[string key]
  3240. {
  3241. get { return _dict1[key]; }
  3242. set { _dict1[key] = value; }
  3243. }
  3244. public T this[int id]
  3245. {
  3246. get { return _dict1.Values.FirstOrDefault(x => x.Id == id); }
  3247. set
  3248. {
  3249. var item = this[id];
  3250. if (item == null)
  3251. Add(value);
  3252. else
  3253. _dict1[item.Key] = value;
  3254. }
  3255. }
  3256. public string ToJson()
  3257. {
  3258. return JsonConvert.SerializeObject(this, Formatting.Indented);
  3259. }
  3260. public T[] TheItems
  3261. {
  3262. get { return _dict1.Values.ToArray<T>(); }
  3263. set
  3264. {
  3265. foreach (var item in value)
  3266. Add(item);
  3267. }
  3268. }
  3269. }
  3270. [Test]
  3271. public void IgnoreIndexedProperties()
  3272. {
  3273. ThisGenericTest<KeyValueId> g = new ThisGenericTest<KeyValueId>();
  3274. g.Add(new KeyValueId { Id = 1, Key = "key1", Value = "value1" });
  3275. g.Add(new KeyValueId { Id = 2, Key = "key2", Value = "value2" });
  3276. g.MyProperty = "some value";
  3277. string json = g.ToJson();
  3278. Assert.AreEqual(@"{
  3279. ""MyProperty"": ""some value"",
  3280. ""TheItems"": [
  3281. {
  3282. ""Id"": 1,
  3283. ""Key"": ""key1"",
  3284. ""Value"": ""value1""
  3285. },
  3286. {
  3287. ""Id"": 2,
  3288. ""Key"": ""key2"",
  3289. ""Value"": ""value2""
  3290. }
  3291. ]
  3292. }", json);
  3293. ThisGenericTest<KeyValueId> gen = JsonConvert.DeserializeObject<ThisGenericTest<KeyValueId>>(json);
  3294. Assert.AreEqual("some value", gen.MyProperty);
  3295. }
  3296. public class JRawValueTestObject
  3297. {
  3298. public JRaw Value { get; set; }
  3299. }
  3300. [Test]
  3301. public void JRawValue()
  3302. {
  3303. JRawValueTestObject deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:3}");
  3304. Assert.AreEqual("3", deserialized.Value.ToString());
  3305. deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:'3'}");
  3306. Assert.AreEqual(@"""3""", deserialized.Value.ToString());
  3307. }
  3308. [Test]
  3309. public void DeserializeDictionaryWithNoDefaultConstructor()
  3310. {
  3311. string json = "{key1:'value1',key2:'value2',key3:'value3'}";
  3312. var dic = JsonConvert.DeserializeObject<DictionaryWithNoDefaultConstructor>(json);
  3313. Assert.AreEqual(3, dic.Count);
  3314. Assert.AreEqual("value1", dic["key1"]);
  3315. Assert.AreEqual("value2", dic["key2"]);
  3316. Assert.AreEqual("value3", dic["key3"]);
  3317. }
  3318. [Test]
  3319. public void DeserializeDictionaryWithNoDefaultConstructor_PreserveReferences()
  3320. {
  3321. string json = "{'$id':'1',key1:'value1',key2:'value2',key3:'value3'}";
  3322. ExceptionAssert.Throws<JsonSerializationException>("Cannot preserve reference to readonly dictionary, or dictionary created from a non-default constructor: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+DictionaryWithNoDefaultConstructor. Path 'key1', line 1, position 16.",
  3323. () => JsonConvert.DeserializeObject<DictionaryWithNoDefaultConstructor>(json, new JsonSerializerSettings
  3324. {
  3325. PreserveReferencesHandling = PreserveReferencesHandling.All,
  3326. SpecialPropertyHandling = SpecialPropertyHandling.Default
  3327. }));
  3328. }
  3329. public class DictionaryWithNoDefaultConstructor : Dictionary<string, string>
  3330. {
  3331. public DictionaryWithNoDefaultConstructor(IEnumerable<KeyValuePair<string, string>> initial)
  3332. {
  3333. foreach (KeyValuePair<string, string> pair in initial)
  3334. {
  3335. Add(pair.Key, pair.Value);
  3336. }
  3337. }
  3338. }
  3339. [JsonObject(MemberSerialization.OptIn)]
  3340. public class A
  3341. {
  3342. [JsonProperty("A1")]
  3343. private string _A1;
  3344. public string A1
  3345. {
  3346. get { return _A1; }
  3347. set { _A1 = value; }
  3348. }
  3349. [JsonProperty("A2")]
  3350. private string A2 { get; set; }
  3351. }
  3352. [JsonObject(MemberSerialization.OptIn)]
  3353. public class B : A
  3354. {
  3355. public string B1 { get; set; }
  3356. [JsonProperty("B2")]
  3357. private string _B2;
  3358. public string B2
  3359. {
  3360. get { return _B2; }
  3361. set { _B2 = value; }
  3362. }
  3363. [JsonProperty("B3")]
  3364. private string B3 { get; set; }
  3365. }
  3366. [Test]
  3367. public void SerializeNonPublicBaseJsonProperties()
  3368. {
  3369. B value = new B();
  3370. string json = JsonConvert.SerializeObject(value, Formatting.Indented);
  3371. Assert.AreEqual(@"{
  3372. ""B2"": null,
  3373. ""A1"": null,
  3374. ""B3"": null,
  3375. ""A2"": null
  3376. }", json);
  3377. }
  3378. public class TestClass
  3379. {
  3380. public string Key { get; set; }
  3381. public object Value { get; set; }
  3382. }
  3383. [Test]
  3384. public void DeserializeToObjectProperty()
  3385. {
  3386. var json = "{ Key: 'abc', Value: 123 }";
  3387. var item = JsonConvert.DeserializeObject<TestClass>(json);
  3388. Assert.AreEqual(123L, item.Value);
  3389. }
  3390. public abstract class Animal
  3391. {
  3392. public abstract string Name { get; }
  3393. }
  3394. public class Human : Animal
  3395. {
  3396. public override string Name
  3397. {
  3398. get { return typeof(Human).Name; }
  3399. }
  3400. public string Ethnicity { get; set; }
  3401. }
  3402. #if !NET20
  3403. public class DataContractJsonSerializerTestClass
  3404. {
  3405. public TimeSpan TimeSpanProperty { get; set; }
  3406. public Guid GuidProperty { get; set; }
  3407. public Animal AnimalProperty { get; set; }
  3408. public Exception ExceptionProperty { get; set; }
  3409. }
  3410. [Test]
  3411. public void DataContractJsonSerializerTest()
  3412. {
  3413. Exception ex = new Exception("Blah blah blah");
  3414. DataContractJsonSerializerTestClass c = new DataContractJsonSerializerTestClass();
  3415. c.TimeSpanProperty = new TimeSpan(200, 20, 59, 30, 900);
  3416. c.GuidProperty = new Guid("66143115-BE2A-4a59-AF0A-348E1EA15B1E");
  3417. c.AnimalProperty = new Human() { Ethnicity = "European" };
  3418. c.ExceptionProperty = ex;
  3419. MemoryStream ms = new MemoryStream();
  3420. DataContractJsonSerializer serializer = new DataContractJsonSerializer(
  3421. typeof(DataContractJsonSerializerTestClass),
  3422. new Type[] { typeof(Human) });
  3423. serializer.WriteObject(ms, c);
  3424. byte[] jsonBytes = ms.ToArray();
  3425. string json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length);
  3426. //Console.WriteLine(JObject.Parse(json).ToString());
  3427. //Console.WriteLine();
  3428. //Console.WriteLine(JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings
  3429. // {
  3430. // // TypeNameHandling = TypeNameHandling.Objects
  3431. // }));
  3432. }
  3433. #endif
  3434. public class ModelStateDictionary<T> : IDictionary<string, T>
  3435. {
  3436. private readonly Dictionary<string, T> _innerDictionary = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
  3437. public ModelStateDictionary()
  3438. {
  3439. }
  3440. public ModelStateDictionary(ModelStateDictionary<T> dictionary)
  3441. {
  3442. if (dictionary == null)
  3443. {
  3444. throw new ArgumentNullException("dictionary");
  3445. }
  3446. foreach (var entry in dictionary)
  3447. {
  3448. _innerDictionary.Add(entry.Key, entry.Value);
  3449. }
  3450. }
  3451. public int Count
  3452. {
  3453. get { return _innerDictionary.Count; }
  3454. }
  3455. public bool IsReadOnly
  3456. {
  3457. get { return ((IDictionary<string, T>)_innerDictionary).IsReadOnly; }
  3458. }
  3459. public ICollection<string> Keys
  3460. {
  3461. get { return _innerDictionary.Keys; }
  3462. }
  3463. public T this[string key]
  3464. {
  3465. get
  3466. {
  3467. T value;
  3468. _innerDictionary.TryGetValue(key, out value);
  3469. return value;
  3470. }
  3471. set { _innerDictionary[key] = value; }
  3472. }
  3473. public ICollection<T> Values
  3474. {
  3475. get { return _innerDictionary.Values; }
  3476. }
  3477. public void Add(KeyValuePair<string, T> item)
  3478. {
  3479. ((IDictionary<string, T>)_innerDictionary).Add(item);
  3480. }
  3481. public void Add(string key, T value)
  3482. {
  3483. _innerDictionary.Add(key, value);
  3484. }
  3485. public void Clear()
  3486. {
  3487. _innerDictionary.Clear();
  3488. }
  3489. public bool Contains(KeyValuePair<string, T> item)
  3490. {
  3491. return ((IDictionary<string, T>)_innerDictionary).Contains(item);
  3492. }
  3493. public bool ContainsKey(string key)
  3494. {
  3495. return _innerDictionary.ContainsKey(key);
  3496. }
  3497. public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
  3498. {
  3499. ((IDictionary<string, T>)_innerDictionary).CopyTo(array, arrayIndex);
  3500. }
  3501. public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
  3502. {
  3503. return _innerDictionary.GetEnumerator();
  3504. }
  3505. public void Merge(ModelStateDictionary<T> dictionary)
  3506. {
  3507. if (dictionary == null)
  3508. {
  3509. return;
  3510. }
  3511. foreach (var entry in dictionary)
  3512. {
  3513. this[entry.Key] = entry.Value;
  3514. }
  3515. }
  3516. public bool Remove(KeyValuePair<string, T> item)
  3517. {
  3518. return ((IDictionary<string, T>)_innerDictionary).Remove(item);
  3519. }
  3520. public bool Remove(string key)
  3521. {
  3522. return _innerDictionary.Remove(key);
  3523. }
  3524. public bool TryGetValue(string key, out T value)
  3525. {
  3526. return _innerDictionary.TryGetValue(key, out value);
  3527. }
  3528. IEnumerator IEnumerable.GetEnumerator()
  3529. {
  3530. return ((IEnumerable)_innerDictionary).GetEnumerator();
  3531. }
  3532. }
  3533. [Test]
  3534. public void SerializeNonIDictionary()
  3535. {
  3536. ModelStateDictionary<string> modelStateDictionary = new ModelStateDictionary<string>();
  3537. modelStateDictionary.Add("key", "value");
  3538. string json = JsonConvert.SerializeObject(modelStateDictionary);
  3539. Assert.AreEqual(@"{""key"":""value""}", json);
  3540. ModelStateDictionary<string> newModelStateDictionary = JsonConvert.DeserializeObject<ModelStateDictionary<string>>(json);
  3541. Assert.AreEqual(1, newModelStateDictionary.Count);
  3542. Assert.AreEqual("value", newModelStateDictionary["key"]);
  3543. }
  3544. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  3545. public class ISerializableTestObject : ISerializable
  3546. {
  3547. internal string _stringValue;
  3548. internal int _intValue;
  3549. internal DateTimeOffset _dateTimeOffsetValue;
  3550. internal Person _personValue;
  3551. internal Person _nullPersonValue;
  3552. internal int? _nullableInt;
  3553. internal bool _booleanValue;
  3554. internal byte _byteValue;
  3555. internal char _charValue;
  3556. internal DateTime _dateTimeValue;
  3557. internal decimal _decimalValue;
  3558. internal short _shortValue;
  3559. internal long _longValue;
  3560. internal sbyte _sbyteValue;
  3561. internal float _floatValue;
  3562. internal ushort _ushortValue;
  3563. internal uint _uintValue;
  3564. internal ulong _ulongValue;
  3565. public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue)
  3566. {
  3567. _stringValue = stringValue;
  3568. _intValue = intValue;
  3569. _dateTimeOffsetValue = dateTimeOffset;
  3570. _personValue = personValue;
  3571. _dateTimeValue = new DateTime(0, DateTimeKind.Utc);
  3572. }
  3573. protected ISerializableTestObject(SerializationInfo info, StreamingContext context)
  3574. {
  3575. _stringValue = info.GetString("stringValue");
  3576. _intValue = info.GetInt32("intValue");
  3577. _dateTimeOffsetValue = (DateTimeOffset)info.GetValue("dateTimeOffsetValue", typeof(DateTimeOffset));
  3578. _personValue = (Person)info.GetValue("personValue", typeof(Person));
  3579. _nullPersonValue = (Person)info.GetValue("nullPersonValue", typeof(Person));
  3580. _nullableInt = (int?)info.GetValue("nullableInt", typeof(int?));
  3581. _booleanValue = info.GetBoolean("booleanValue");
  3582. _byteValue = info.GetByte("byteValue");
  3583. _charValue = info.GetChar("charValue");
  3584. _dateTimeValue = info.GetDateTime("dateTimeValue");
  3585. _decimalValue = info.GetDecimal("decimalValue");
  3586. _shortValue = info.GetInt16("shortValue");
  3587. _longValue = info.GetInt64("longValue");
  3588. _sbyteValue = info.GetSByte("sbyteValue");
  3589. _floatValue = info.GetSingle("floatValue");
  3590. _ushortValue = info.GetUInt16("ushortValue");
  3591. _uintValue = info.GetUInt32("uintValue");
  3592. _ulongValue = info.GetUInt64("ulongValue");
  3593. }
  3594. public void GetObjectData(SerializationInfo info, StreamingContext context)
  3595. {
  3596. info.AddValue("stringValue", _stringValue);
  3597. info.AddValue("intValue", _intValue);
  3598. info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue);
  3599. info.AddValue("personValue", _personValue);
  3600. info.AddValue("nullPersonValue", _nullPersonValue);
  3601. info.AddValue("nullableInt", null);
  3602. info.AddValue("booleanValue", _booleanValue);
  3603. info.AddValue("byteValue", _byteValue);
  3604. info.AddValue("charValue", _charValue);
  3605. info.AddValue("dateTimeValue", _dateTimeValue);
  3606. info.AddValue("decimalValue", _decimalValue);
  3607. info.AddValue("shortValue", _shortValue);
  3608. info.AddValue("longValue", _longValue);
  3609. info.AddValue("sbyteValue", _sbyteValue);
  3610. info.AddValue("floatValue", _floatValue);
  3611. info.AddValue("ushortValue", _ushortValue);
  3612. info.AddValue("uintValue", _uintValue);
  3613. info.AddValue("ulongValue", _ulongValue);
  3614. }
  3615. }
  3616. #if DEBUG
  3617. [Test]
  3618. public void SerializeISerializableInPartialTrustWithIgnoreInterface()
  3619. {
  3620. try
  3621. {
  3622. JsonTypeReflector.SetFullyTrusted(false);
  3623. ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null);
  3624. string json = JsonConvert.SerializeObject(value, new JsonSerializerSettings
  3625. {
  3626. ContractResolver = new DefaultContractResolver(false)
  3627. {
  3628. IgnoreSerializableInterface = true
  3629. }
  3630. });
  3631. Assert.AreEqual("{}", json);
  3632. value = JsonConvert.DeserializeObject<ISerializableTestObject>("{booleanValue:true}", new JsonSerializerSettings
  3633. {
  3634. ContractResolver = new DefaultContractResolver(false)
  3635. {
  3636. IgnoreSerializableInterface = true
  3637. }
  3638. });
  3639. Assert.IsNotNull(value);
  3640. Assert.AreEqual(false, value._booleanValue);
  3641. }
  3642. finally
  3643. {
  3644. JsonTypeReflector.SetFullyTrusted(true);
  3645. }
  3646. }
  3647. [Test]
  3648. public void SerializeISerializableInPartialTrust()
  3649. {
  3650. try
  3651. {
  3652. ExceptionAssert.Throws<JsonSerializationException>(
  3653. @"Type 'Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+ISerializableTestObject' implements ISerializable but cannot be deserialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
  3654. To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.
  3655. Path 'booleanValue', line 1, position 14.",
  3656. () =>
  3657. {
  3658. JsonTypeReflector.SetFullyTrusted(false);
  3659. JsonConvert.DeserializeObject<ISerializableTestObject>("{booleanValue:true}");
  3660. });
  3661. }
  3662. finally
  3663. {
  3664. JsonTypeReflector.SetFullyTrusted(true);
  3665. }
  3666. }
  3667. [Test]
  3668. public void DeserializeISerializableInPartialTrust()
  3669. {
  3670. try
  3671. {
  3672. ExceptionAssert.Throws<JsonSerializationException>(
  3673. @"Type 'Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+ISerializableTestObject' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
  3674. To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true. Path ''.",
  3675. () =>
  3676. {
  3677. JsonTypeReflector.SetFullyTrusted(false);
  3678. ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null);
  3679. JsonConvert.SerializeObject(value);
  3680. });
  3681. }
  3682. finally
  3683. {
  3684. JsonTypeReflector.SetFullyTrusted(true);
  3685. }
  3686. }
  3687. #endif
  3688. [Test]
  3689. public void SerializeISerializableTestObject_IsoDate()
  3690. {
  3691. Person person = new Person();
  3692. person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
  3693. person.LastModified = person.BirthDate;
  3694. person.Department = "Department!";
  3695. person.Name = "Name!";
  3696. DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2));
  3697. string dateTimeOffsetText;
  3698. #if !NET20
  3699. dateTimeOffsetText = @"2000-12-20T22:59:59+02:00";
  3700. #else
  3701. dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00";
  3702. #endif
  3703. ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person);
  3704. string json = JsonConvert.SerializeObject(o, Formatting.Indented);
  3705. Assert.AreEqual(@"{
  3706. ""stringValue"": ""String!"",
  3707. ""intValue"": -2147483648,
  3708. ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""",
  3709. ""personValue"": {
  3710. ""Name"": ""Name!"",
  3711. ""BirthDate"": ""2000-01-01T01:01:01Z"",
  3712. ""LastModified"": ""2000-01-01T01:01:01Z""
  3713. },
  3714. ""nullPersonValue"": null,
  3715. ""nullableInt"": null,
  3716. ""booleanValue"": false,
  3717. ""byteValue"": 0,
  3718. ""charValue"": ""\u0000"",
  3719. ""dateTimeValue"": ""0001-01-01T00:00:00Z"",
  3720. ""decimalValue"": 0.0,
  3721. ""shortValue"": 0,
  3722. ""longValue"": 0,
  3723. ""sbyteValue"": 0,
  3724. ""floatValue"": 0.0,
  3725. ""ushortValue"": 0,
  3726. ""uintValue"": 0,
  3727. ""ulongValue"": 0
  3728. }", json);
  3729. ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
  3730. Assert.AreEqual("String!", o2._stringValue);
  3731. Assert.AreEqual(int.MinValue, o2._intValue);
  3732. Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
  3733. Assert.AreEqual("Name!", o2._personValue.Name);
  3734. Assert.AreEqual(null, o2._nullPersonValue);
  3735. Assert.AreEqual(null, o2._nullableInt);
  3736. }
  3737. [Test]
  3738. public void SerializeISerializableTestObject_MsAjax()
  3739. {
  3740. Person person = new Person();
  3741. person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
  3742. person.LastModified = person.BirthDate;
  3743. person.Department = "Department!";
  3744. person.Name = "Name!";
  3745. DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2));
  3746. string dateTimeOffsetText;
  3747. #if !NET20
  3748. dateTimeOffsetText = @"\/Date(977345999000+0200)\/";
  3749. #else
  3750. dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00";
  3751. #endif
  3752. ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person);
  3753. string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings
  3754. {
  3755. DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
  3756. });
  3757. Assert.AreEqual(@"{
  3758. ""stringValue"": ""String!"",
  3759. ""intValue"": -2147483648,
  3760. ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""",
  3761. ""personValue"": {
  3762. ""Name"": ""Name!"",
  3763. ""BirthDate"": ""\/Date(946688461000)\/"",
  3764. ""LastModified"": ""\/Date(946688461000)\/""
  3765. },
  3766. ""nullPersonValue"": null,
  3767. ""nullableInt"": null,
  3768. ""booleanValue"": false,
  3769. ""byteValue"": 0,
  3770. ""charValue"": ""\u0000"",
  3771. ""dateTimeValue"": ""\/Date(-62135596800000)\/"",
  3772. ""decimalValue"": 0.0,
  3773. ""shortValue"": 0,
  3774. ""longValue"": 0,
  3775. ""sbyteValue"": 0,
  3776. ""floatValue"": 0.0,
  3777. ""ushortValue"": 0,
  3778. ""uintValue"": 0,
  3779. ""ulongValue"": 0
  3780. }", json);
  3781. ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
  3782. Assert.AreEqual("String!", o2._stringValue);
  3783. Assert.AreEqual(int.MinValue, o2._intValue);
  3784. Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
  3785. Assert.AreEqual("Name!", o2._personValue.Name);
  3786. Assert.AreEqual(null, o2._nullPersonValue);
  3787. Assert.AreEqual(null, o2._nullableInt);
  3788. }
  3789. #endif
  3790. public class KVPair<TKey, TValue>
  3791. {
  3792. public TKey Key { get; set; }
  3793. public TValue Value { get; set; }
  3794. public KVPair(TKey k, TValue v)
  3795. {
  3796. Key = k;
  3797. Value = v;
  3798. }
  3799. }
  3800. [Test]
  3801. public void DeserializeUsingNonDefaultConstructorWithLeftOverValues()
  3802. {
  3803. List<KVPair<string, string>> kvPairs =
  3804. JsonConvert.DeserializeObject<List<KVPair<string, string>>>(
  3805. "[{\"Key\":\"Two\",\"Value\":\"2\"},{\"Key\":\"One\",\"Value\":\"1\"}]");
  3806. Assert.AreEqual(2, kvPairs.Count);
  3807. Assert.AreEqual("Two", kvPairs[0].Key);
  3808. Assert.AreEqual("2", kvPairs[0].Value);
  3809. Assert.AreEqual("One", kvPairs[1].Key);
  3810. Assert.AreEqual("1", kvPairs[1].Value);
  3811. }
  3812. [Test]
  3813. public void SerializeClassWithInheritedProtectedMember()
  3814. {
  3815. AA myA = new AA(2);
  3816. string json = JsonConvert.SerializeObject(myA, Formatting.Indented);
  3817. Assert.AreEqual(@"{
  3818. ""AA_field1"": 2,
  3819. ""AA_property1"": 2,
  3820. ""AA_property2"": 2,
  3821. ""AA_property3"": 2,
  3822. ""AA_property4"": 2
  3823. }", json);
  3824. BB myB = new BB(3, 4);
  3825. json = JsonConvert.SerializeObject(myB, Formatting.Indented);
  3826. Assert.AreEqual(@"{
  3827. ""BB_field1"": 4,
  3828. ""BB_field2"": 4,
  3829. ""AA_field1"": 3,
  3830. ""BB_property1"": 4,
  3831. ""BB_property2"": 4,
  3832. ""BB_property3"": 4,
  3833. ""BB_property4"": 4,
  3834. ""BB_property5"": 4,
  3835. ""BB_property7"": 4,
  3836. ""AA_property1"": 3,
  3837. ""AA_property2"": 3,
  3838. ""AA_property3"": 3,
  3839. ""AA_property4"": 3
  3840. }", json);
  3841. }
  3842. #if !PORTABLE
  3843. [Test]
  3844. public void DeserializeClassWithInheritedProtectedMember()
  3845. {
  3846. AA myA = JsonConvert.DeserializeObject<AA>(
  3847. @"{
  3848. ""AA_field1"": 2,
  3849. ""AA_field2"": 2,
  3850. ""AA_property1"": 2,
  3851. ""AA_property2"": 2,
  3852. ""AA_property3"": 2,
  3853. ""AA_property4"": 2,
  3854. ""AA_property5"": 2,
  3855. ""AA_property6"": 2
  3856. }");
  3857. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3858. Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3859. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3860. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3861. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3862. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3863. Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3864. Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myA));
  3865. BB myB = JsonConvert.DeserializeObject<BB>(
  3866. @"{
  3867. ""BB_field1"": 4,
  3868. ""BB_field2"": 4,
  3869. ""AA_field1"": 3,
  3870. ""AA_field2"": 3,
  3871. ""AA_property1"": 2,
  3872. ""AA_property2"": 2,
  3873. ""AA_property3"": 2,
  3874. ""AA_property4"": 2,
  3875. ""AA_property5"": 2,
  3876. ""AA_property6"": 2,
  3877. ""BB_property1"": 3,
  3878. ""BB_property2"": 3,
  3879. ""BB_property3"": 3,
  3880. ""BB_property4"": 3,
  3881. ""BB_property5"": 3,
  3882. ""BB_property6"": 3,
  3883. ""BB_property7"": 3,
  3884. ""BB_property8"": 3
  3885. }");
  3886. Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3887. Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3888. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3889. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3890. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3891. Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3892. Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3893. Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3894. Assert.AreEqual(4, myB.BB_field1);
  3895. Assert.AreEqual(4, myB.BB_field2);
  3896. Assert.AreEqual(3, myB.BB_property1);
  3897. Assert.AreEqual(3, myB.BB_property2);
  3898. Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property3", BindingFlags.Instance | BindingFlags.Public), myB));
  3899. Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
  3900. Assert.AreEqual(0, myB.BB_property5);
  3901. Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property6", BindingFlags.Instance | BindingFlags.Public), myB));
  3902. Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property7", BindingFlags.Instance | BindingFlags.Public), myB));
  3903. Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property8", BindingFlags.Instance | BindingFlags.Public), myB));
  3904. }
  3905. #endif
  3906. public class AA
  3907. {
  3908. [JsonProperty]
  3909. protected int AA_field1;
  3910. protected int AA_field2;
  3911. [JsonProperty]
  3912. protected int AA_property1 { get; set; }
  3913. [JsonProperty]
  3914. protected int AA_property2 { get; private set; }
  3915. [JsonProperty]
  3916. protected int AA_property3 { private get; set; }
  3917. [JsonProperty]
  3918. private int AA_property4 { get; set; }
  3919. protected int AA_property5 { get; private set; }
  3920. protected int AA_property6 { private get; set; }
  3921. public AA()
  3922. {
  3923. }
  3924. public AA(int f)
  3925. {
  3926. AA_field1 = f;
  3927. AA_field2 = f;
  3928. AA_property1 = f;
  3929. AA_property2 = f;
  3930. AA_property3 = f;
  3931. AA_property4 = f;
  3932. AA_property5 = f;
  3933. AA_property6 = f;
  3934. }
  3935. }
  3936. public class BB : AA
  3937. {
  3938. [JsonProperty]
  3939. public int BB_field1;
  3940. public int BB_field2;
  3941. [JsonProperty]
  3942. public int BB_property1 { get; set; }
  3943. [JsonProperty]
  3944. public int BB_property2 { get; private set; }
  3945. [JsonProperty]
  3946. public int BB_property3 { private get; set; }
  3947. [JsonProperty]
  3948. private int BB_property4 { get; set; }
  3949. public int BB_property5 { get; private set; }
  3950. public int BB_property6 { private get; set; }
  3951. [JsonProperty]
  3952. public int BB_property7 { protected get; set; }
  3953. public int BB_property8 { protected get; set; }
  3954. public BB()
  3955. {
  3956. }
  3957. public BB(int f, int g)
  3958. : base(f)
  3959. {
  3960. BB_field1 = g;
  3961. BB_field2 = g;
  3962. BB_property1 = g;
  3963. BB_property2 = g;
  3964. BB_property3 = g;
  3965. BB_property4 = g;
  3966. BB_property5 = g;
  3967. BB_property6 = g;
  3968. BB_property7 = g;
  3969. BB_property8 = g;
  3970. }
  3971. }
  3972. #if !NET20
  3973. public class XNodeTestObject
  3974. {
  3975. public XDocument Document { get; set; }
  3976. public XElement Element { get; set; }
  3977. }
  3978. #endif
  3979. #if !NETFX_CORE
  3980. public class XmlNodeTestObject
  3981. {
  3982. public XmlDocument Document { get; set; }
  3983. }
  3984. #endif
  3985. #if !(NET20 || PORTABLE40)
  3986. [Test]
  3987. public void SerializeDeserializeXNodeProperties()
  3988. {
  3989. XNodeTestObject testObject = new XNodeTestObject();
  3990. testObject.Document = XDocument.Parse("<root>hehe, root</root>");
  3991. testObject.Element = XElement.Parse(@"<fifth xmlns:json=""http://json.org"" json:Awesome=""true"">element</fifth>");
  3992. string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
  3993. string expected = @"{
  3994. ""Document"": {
  3995. ""root"": ""hehe, root""
  3996. },
  3997. ""Element"": {
  3998. ""fifth"": {
  3999. ""@xmlns:json"": ""http://json.org"",
  4000. ""@json:Awesome"": ""true"",
  4001. ""#text"": ""element""
  4002. }
  4003. }
  4004. }";
  4005. Assert.AreEqual(expected, json);
  4006. XNodeTestObject newTestObject = JsonConvert.DeserializeObject<XNodeTestObject>(json);
  4007. Assert.AreEqual(testObject.Document.ToString(), newTestObject.Document.ToString());
  4008. Assert.AreEqual(testObject.Element.ToString(), newTestObject.Element.ToString());
  4009. Assert.IsNull(newTestObject.Element.Parent);
  4010. }
  4011. #endif
  4012. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  4013. [Test]
  4014. public void SerializeDeserializeXmlNodeProperties()
  4015. {
  4016. XmlNodeTestObject testObject = new XmlNodeTestObject();
  4017. XmlDocument document = new XmlDocument();
  4018. document.LoadXml("<root>hehe, root</root>");
  4019. testObject.Document = document;
  4020. string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
  4021. string expected = @"{
  4022. ""Document"": {
  4023. ""root"": ""hehe, root""
  4024. }
  4025. }";
  4026. Assert.AreEqual(expected, json);
  4027. XmlNodeTestObject newTestObject = JsonConvert.DeserializeObject<XmlNodeTestObject>(json);
  4028. Assert.AreEqual(testObject.Document.InnerXml, newTestObject.Document.InnerXml);
  4029. }
  4030. #endif
  4031. [Test]
  4032. public void FullClientMapSerialization()
  4033. {
  4034. ClientMap source = new ClientMap()
  4035. {
  4036. position = new Pos() { X = 100, Y = 200 },
  4037. center = new PosDouble() { X = 251.6, Y = 361.3 }
  4038. };
  4039. string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter());
  4040. Assert.AreEqual("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}", json);
  4041. }
  4042. public class ClientMap
  4043. {
  4044. public Pos position { get; set; }
  4045. public PosDouble center { get; set; }
  4046. }
  4047. public class Pos
  4048. {
  4049. public int X { get; set; }
  4050. public int Y { get; set; }
  4051. }
  4052. public class PosDouble
  4053. {
  4054. public double X { get; set; }
  4055. public double Y { get; set; }
  4056. }
  4057. public class PosConverter : JsonConverter
  4058. {
  4059. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  4060. {
  4061. Pos p = (Pos)value;
  4062. if (p != null)
  4063. writer.WriteRawValue(String.Format("new Pos({0},{1})", p.X, p.Y));
  4064. else
  4065. writer.WriteNull();
  4066. }
  4067. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  4068. {
  4069. throw new NotImplementedException();
  4070. }
  4071. public override bool CanConvert(Type objectType)
  4072. {
  4073. return objectType.IsAssignableFrom(typeof(Pos));
  4074. }
  4075. }
  4076. public class PosDoubleConverter : JsonConverter
  4077. {
  4078. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  4079. {
  4080. PosDouble p = (PosDouble)value;
  4081. if (p != null)
  4082. writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y));
  4083. else
  4084. writer.WriteNull();
  4085. }
  4086. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  4087. {
  4088. throw new NotImplementedException();
  4089. }
  4090. public override bool CanConvert(Type objectType)
  4091. {
  4092. return objectType.IsAssignableFrom(typeof(PosDouble));
  4093. }
  4094. }
  4095. [Test]
  4096. public void TestEscapeDictionaryStrings()
  4097. {
  4098. const string s = @"host\user";
  4099. string serialized = JsonConvert.SerializeObject(s);
  4100. Assert.AreEqual(@"""host\\user""", serialized);
  4101. Dictionary<int, object> d1 = new Dictionary<int, object>();
  4102. d1.Add(5, s);
  4103. Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1));
  4104. Dictionary<string, object> d2 = new Dictionary<string, object>();
  4105. d2.Add(s, 5);
  4106. Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2));
  4107. }
  4108. public class GenericListTestClass
  4109. {
  4110. public List<string> GenericList { get; set; }
  4111. public GenericListTestClass()
  4112. {
  4113. GenericList = new List<string>();
  4114. }
  4115. }
  4116. [Test]
  4117. public void DeserializeExistingGenericList()
  4118. {
  4119. GenericListTestClass c = new GenericListTestClass();
  4120. c.GenericList.Add("1");
  4121. c.GenericList.Add("2");
  4122. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  4123. GenericListTestClass newValue = JsonConvert.DeserializeObject<GenericListTestClass>(json);
  4124. Assert.AreEqual(2, newValue.GenericList.Count);
  4125. Assert.AreEqual(typeof(List<string>), newValue.GenericList.GetType());
  4126. }
  4127. [Test]
  4128. public void DeserializeSimpleKeyValuePair()
  4129. {
  4130. List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
  4131. list.Add(new KeyValuePair<string, string>("key1", "value1"));
  4132. list.Add(new KeyValuePair<string, string>("key2", "value2"));
  4133. string json = JsonConvert.SerializeObject(list);
  4134. Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json);
  4135. List<KeyValuePair<string, string>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, string>>>(json);
  4136. Assert.AreEqual(2, result.Count);
  4137. Assert.AreEqual("key1", result[0].Key);
  4138. Assert.AreEqual("value1", result[0].Value);
  4139. Assert.AreEqual("key2", result[1].Key);
  4140. Assert.AreEqual("value2", result[1].Value);
  4141. }
  4142. [Test]
  4143. public void DeserializeComplexKeyValuePair()
  4144. {
  4145. DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc);
  4146. List<KeyValuePair<string, WagePerson>> list = new List<KeyValuePair<string, WagePerson>>();
  4147. list.Add(new KeyValuePair<string, WagePerson>("key1", new WagePerson
  4148. {
  4149. BirthDate = dateTime,
  4150. Department = "Department1",
  4151. LastModified = dateTime,
  4152. HourlyWage = 1
  4153. }));
  4154. list.Add(new KeyValuePair<string, WagePerson>("key2", new WagePerson
  4155. {
  4156. BirthDate = dateTime,
  4157. Department = "Department2",
  4158. LastModified = dateTime,
  4159. HourlyWage = 2
  4160. }));
  4161. string json = JsonConvert.SerializeObject(list, Formatting.Indented);
  4162. Assert.AreEqual(@"[
  4163. {
  4164. ""Key"": ""key1"",
  4165. ""Value"": {
  4166. ""HourlyWage"": 1.0,
  4167. ""Name"": null,
  4168. ""BirthDate"": ""2000-12-01T23:01:01Z"",
  4169. ""LastModified"": ""2000-12-01T23:01:01Z""
  4170. }
  4171. },
  4172. {
  4173. ""Key"": ""key2"",
  4174. ""Value"": {
  4175. ""HourlyWage"": 2.0,
  4176. ""Name"": null,
  4177. ""BirthDate"": ""2000-12-01T23:01:01Z"",
  4178. ""LastModified"": ""2000-12-01T23:01:01Z""
  4179. }
  4180. }
  4181. ]", json);
  4182. List<KeyValuePair<string, WagePerson>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, WagePerson>>>(json);
  4183. Assert.AreEqual(2, result.Count);
  4184. Assert.AreEqual("key1", result[0].Key);
  4185. Assert.AreEqual(1, result[0].Value.HourlyWage);
  4186. Assert.AreEqual("key2", result[1].Key);
  4187. Assert.AreEqual(2, result[1].Value.HourlyWage);
  4188. }
  4189. public class StringListAppenderConverter : JsonConverter
  4190. {
  4191. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  4192. {
  4193. writer.WriteValue(value);
  4194. }
  4195. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  4196. {
  4197. List<string> existingStrings = (List<string>)existingValue;
  4198. List<string> newStrings = new List<string>(existingStrings);
  4199. reader.Read();
  4200. while (reader.TokenType != JsonToken.EndArray)
  4201. {
  4202. string s = (string)reader.Value;
  4203. newStrings.Add(s);
  4204. reader.Read();
  4205. }
  4206. return newStrings;
  4207. }
  4208. public override bool CanConvert(Type objectType)
  4209. {
  4210. return (objectType == typeof(List<string>));
  4211. }
  4212. }
  4213. [Test]
  4214. public void StringListAppenderConverterTest()
  4215. {
  4216. Movie p = new Movie();
  4217. p.ReleaseCountries = new List<string> { "Existing" };
  4218. JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings
  4219. {
  4220. Converters = new List<JsonConverter> { new StringListAppenderConverter() }
  4221. });
  4222. Assert.AreEqual(2, p.ReleaseCountries.Count);
  4223. Assert.AreEqual("Existing", p.ReleaseCountries[0]);
  4224. Assert.AreEqual("Appended", p.ReleaseCountries[1]);
  4225. }
  4226. public class StringAppenderConverter : JsonConverter
  4227. {
  4228. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  4229. {
  4230. writer.WriteValue(value);
  4231. }
  4232. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  4233. {
  4234. string existingString = (string)existingValue;
  4235. string newString = existingString + (string)reader.Value;
  4236. return newString;
  4237. }
  4238. public override bool CanConvert(Type objectType)
  4239. {
  4240. return (objectType == typeof(string));
  4241. }
  4242. }
  4243. [Test]
  4244. public void StringAppenderConverterTest()
  4245. {
  4246. Movie p = new Movie();
  4247. p.Name = "Existing,";
  4248. JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings
  4249. {
  4250. Converters = new List<JsonConverter> { new StringAppenderConverter() }
  4251. });
  4252. Assert.AreEqual("Existing,Appended", p.Name);
  4253. }
  4254. [Test]
  4255. public void SerializeRefAdditionalContent()
  4256. {
  4257. //Additional text found in JSON string after finishing deserializing object.
  4258. //Test 1
  4259. var reference = new Dictionary<string, object>();
  4260. reference.Add("$ref", "Persons");
  4261. reference.Add("$id", 1);
  4262. var child = new Dictionary<string, object>();
  4263. child.Add("_id", 2);
  4264. child.Add("Name", "Isabell");
  4265. child.Add("Father", reference);
  4266. var json = JsonConvert.SerializeObject(child, Formatting.Indented);
  4267. ExceptionAssert.Throws<JsonSerializationException>(
  4268. "Additional content found in JSON reference object. A JSON reference object should only have a $ref property. Path 'Father.$id', line 6, position 11.",
  4269. () => { JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
  4270. }
  4271. [Test]
  4272. public void SerializeRefBadType()
  4273. {
  4274. ExceptionAssert.Throws<JsonSerializationException>(
  4275. "JSON reference $ref property must have a string or null value. Path 'Father.$ref', line 5, position 14.",
  4276. () =>
  4277. {
  4278. //Additional text found in JSON string after finishing deserializing object.
  4279. //Test 1
  4280. var reference = new Dictionary<string, object>();
  4281. reference.Add("$ref", 1);
  4282. reference.Add("$id", 1);
  4283. var child = new Dictionary<string, object>();
  4284. child.Add("_id", 2);
  4285. child.Add("Name", "Isabell");
  4286. child.Add("Father", reference);
  4287. var json = JsonConvert.SerializeObject(child, Formatting.Indented);
  4288. JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
  4289. });
  4290. }
  4291. [Test]
  4292. public void SerializeRefNull()
  4293. {
  4294. var reference = new Dictionary<string, object>();
  4295. reference.Add("$ref", null);
  4296. reference.Add("$id", null);
  4297. reference.Add("blah", "blah!");
  4298. var child = new Dictionary<string, object>();
  4299. child.Add("_id", 2);
  4300. child.Add("Name", "Isabell");
  4301. child.Add("Father", reference);
  4302. string json = JsonConvert.SerializeObject(child);
  4303. Console.WriteLine(json);
  4304. Dictionary<string, object> result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
  4305. Assert.AreEqual(3, result.Count);
  4306. Assert.AreEqual(1, ((JObject)result["Father"]).Count);
  4307. Assert.AreEqual("blah!", (string)((JObject)result["Father"])["blah"]);
  4308. }
  4309. public class ConstructorCompexIgnoredProperty
  4310. {
  4311. [JsonIgnore]
  4312. public Product Ignored { get; set; }
  4313. public string First { get; set; }
  4314. public int Second { get; set; }
  4315. public ConstructorCompexIgnoredProperty(string first, int second)
  4316. {
  4317. First = first;
  4318. Second = second;
  4319. }
  4320. }
  4321. [Test]
  4322. public void DeserializeIgnoredPropertyInConstructor()
  4323. {
  4324. string json = @"{""First"":""First"",""Second"":2,""Ignored"":{""Name"":""James""},""AdditionalContent"":{""LOL"":true}}";
  4325. ConstructorCompexIgnoredProperty cc = JsonConvert.DeserializeObject<ConstructorCompexIgnoredProperty>(json);
  4326. Assert.AreEqual("First", cc.First);
  4327. Assert.AreEqual(2, cc.Second);
  4328. Assert.AreEqual(null, cc.Ignored);
  4329. }
  4330. [Test]
  4331. public void DeserializeFloatAsDecimal()
  4332. {
  4333. string json = @"{'value':9.9}";
  4334. var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(
  4335. json, new JsonSerializerSettings
  4336. {
  4337. FloatParseHandling = FloatParseHandling.Decimal
  4338. });
  4339. Assert.AreEqual(typeof(decimal), dic["value"].GetType());
  4340. Assert.AreEqual(9.9m, dic["value"]);
  4341. }
  4342. [Test]
  4343. public void ShouldSerializeTest()
  4344. {
  4345. ShouldSerializeTestClass c = new ShouldSerializeTestClass();
  4346. c.Name = "James";
  4347. c.Age = 27;
  4348. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  4349. Assert.AreEqual(@"{
  4350. ""Age"": 27
  4351. }", json);
  4352. c._shouldSerializeName = true;
  4353. json = JsonConvert.SerializeObject(c, Formatting.Indented);
  4354. Assert.AreEqual(@"{
  4355. ""Name"": ""James"",
  4356. ""Age"": 27
  4357. }", json);
  4358. ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject<ShouldSerializeTestClass>(json);
  4359. Assert.AreEqual("James", deserialized.Name);
  4360. Assert.AreEqual(27, deserialized.Age);
  4361. }
  4362. public class Employee
  4363. {
  4364. public string Name { get; set; }
  4365. public Employee Manager { get; set; }
  4366. public bool ShouldSerializeManager()
  4367. {
  4368. return (Manager != this);
  4369. }
  4370. }
  4371. [Test]
  4372. public void ShouldSerializeExample()
  4373. {
  4374. Employee joe = new Employee();
  4375. joe.Name = "Joe Employee";
  4376. Employee mike = new Employee();
  4377. mike.Name = "Mike Manager";
  4378. joe.Manager = mike;
  4379. mike.Manager = mike;
  4380. string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented);
  4381. // [
  4382. // {
  4383. // "Name": "Joe Employee",
  4384. // "Manager": {
  4385. // "Name": "Mike Manager"
  4386. // }
  4387. // },
  4388. // {
  4389. // "Name": "Mike Manager"
  4390. // }
  4391. // ]
  4392. Console.WriteLine(json);
  4393. }
  4394. [Test]
  4395. public void SpecifiedTest()
  4396. {
  4397. SpecifiedTestClass c = new SpecifiedTestClass();
  4398. c.Name = "James";
  4399. c.Age = 27;
  4400. c.NameSpecified = false;
  4401. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  4402. Assert.AreEqual(@"{
  4403. ""Age"": 27
  4404. }", json);
  4405. SpecifiedTestClass deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
  4406. Assert.IsNull(deserialized.Name);
  4407. Assert.IsFalse(deserialized.NameSpecified);
  4408. Assert.IsFalse(deserialized.WeightSpecified);
  4409. Assert.IsFalse(deserialized.HeightSpecified);
  4410. Assert.IsFalse(deserialized.FavoriteNumberSpecified);
  4411. Assert.AreEqual(27, deserialized.Age);
  4412. c.NameSpecified = true;
  4413. c.WeightSpecified = true;
  4414. c.HeightSpecified = true;
  4415. c.FavoriteNumber = 23;
  4416. json = JsonConvert.SerializeObject(c, Formatting.Indented);
  4417. Assert.AreEqual(@"{
  4418. ""Name"": ""James"",
  4419. ""Age"": 27,
  4420. ""Weight"": 0,
  4421. ""Height"": 0,
  4422. ""FavoriteNumber"": 23
  4423. }", json);
  4424. deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
  4425. Assert.AreEqual("James", deserialized.Name);
  4426. Assert.IsTrue(deserialized.NameSpecified);
  4427. Assert.IsTrue(deserialized.WeightSpecified);
  4428. Assert.IsTrue(deserialized.HeightSpecified);
  4429. Assert.IsTrue(deserialized.FavoriteNumberSpecified);
  4430. Assert.AreEqual(27, deserialized.Age);
  4431. Assert.AreEqual(23, deserialized.FavoriteNumber);
  4432. }
  4433. // [Test]
  4434. // public void XmlSerializerSpecifiedTrueTest()
  4435. // {
  4436. // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
  4437. // StringWriter sw = new StringWriter();
  4438. // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true });
  4439. // Console.WriteLine(sw.ToString());
  4440. // string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
  4441. //<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
  4442. // <FirstOrder>First</FirstOrder>
  4443. //</OptionalOrder>";
  4444. // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
  4445. // Console.WriteLine(o.FirstOrder);
  4446. // Console.WriteLine(o.FirstOrderSpecified);
  4447. // }
  4448. // [Test]
  4449. // public void XmlSerializerSpecifiedFalseTest()
  4450. // {
  4451. // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
  4452. // StringWriter sw = new StringWriter();
  4453. // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false });
  4454. // Console.WriteLine(sw.ToString());
  4455. // // string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
  4456. // //<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
  4457. // // <FirstOrder>First</FirstOrder>
  4458. // //</OptionalOrder>";
  4459. // // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
  4460. // // Console.WriteLine(o.FirstOrder);
  4461. // // Console.WriteLine(o.FirstOrderSpecified);
  4462. // }
  4463. public class OptionalOrder
  4464. {
  4465. // This field shouldn't be serialized
  4466. // if it is uninitialized.
  4467. public string FirstOrder;
  4468. // Use the XmlIgnoreAttribute to ignore the
  4469. // special field named "FirstOrderSpecified".
  4470. [System.Xml.Serialization.XmlIgnoreAttribute]
  4471. public bool FirstOrderSpecified;
  4472. }
  4473. public class FamilyDetails
  4474. {
  4475. public string Name { get; set; }
  4476. public int NumberOfChildren { get; set; }
  4477. [JsonIgnore]
  4478. public bool NumberOfChildrenSpecified { get; set; }
  4479. }
  4480. [Test]
  4481. public void SpecifiedExample()
  4482. {
  4483. FamilyDetails joe = new FamilyDetails();
  4484. joe.Name = "Joe Family Details";
  4485. joe.NumberOfChildren = 4;
  4486. joe.NumberOfChildrenSpecified = true;
  4487. FamilyDetails martha = new FamilyDetails();
  4488. martha.Name = "Martha Family Details";
  4489. martha.NumberOfChildren = 3;
  4490. martha.NumberOfChildrenSpecified = false;
  4491. string json = JsonConvert.SerializeObject(new[] { joe, martha }, Formatting.Indented);
  4492. //[
  4493. // {
  4494. // "Name": "Joe Family Details",
  4495. // "NumberOfChildren": 4
  4496. // },
  4497. // {
  4498. // "Name": "Martha Family Details"
  4499. // }
  4500. //]
  4501. Console.WriteLine(json);
  4502. string mikeString = "{\"Name\": \"Mike Person\"}";
  4503. FamilyDetails mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeString);
  4504. Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
  4505. string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}";
  4506. mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeFullDisclosureString);
  4507. Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
  4508. }
  4509. public class DictionaryKey
  4510. {
  4511. public string Value { get; set; }
  4512. public override string ToString()
  4513. {
  4514. return Value;
  4515. }
  4516. public static implicit operator DictionaryKey(string value)
  4517. {
  4518. return new DictionaryKey() { Value = value };
  4519. }
  4520. }
  4521. [Test]
  4522. public void SerializeDeserializeDictionaryKey()
  4523. {
  4524. Dictionary<DictionaryKey, string> dictionary = new Dictionary<DictionaryKey, string>();
  4525. dictionary.Add(new DictionaryKey() { Value = "First!" }, "First");
  4526. dictionary.Add(new DictionaryKey() { Value = "Second!" }, "Second");
  4527. string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
  4528. Assert.AreEqual(@"{
  4529. ""First!"": ""First"",
  4530. ""Second!"": ""Second""
  4531. }", json);
  4532. Dictionary<DictionaryKey, string> newDictionary =
  4533. JsonConvert.DeserializeObject<Dictionary<DictionaryKey, string>>(json);
  4534. Assert.AreEqual(2, newDictionary.Count);
  4535. }
  4536. [Test]
  4537. public void SerializeNullableArray()
  4538. {
  4539. string jsonText = JsonConvert.SerializeObject(new double?[] { 2.4, 4.3, null }, Formatting.Indented);
  4540. Assert.AreEqual(@"[
  4541. 2.4,
  4542. 4.3,
  4543. null
  4544. ]", jsonText);
  4545. }
  4546. [Test]
  4547. public void DeserializeNullableArray()
  4548. {
  4549. double?[] d = (double?[])JsonConvert.DeserializeObject(@"[
  4550. 2.4,
  4551. 4.3,
  4552. null
  4553. ]", typeof(double?[]));
  4554. Assert.AreEqual(3, d.Length);
  4555. Assert.AreEqual(2.4, d[0]);
  4556. Assert.AreEqual(4.3, d[1]);
  4557. Assert.AreEqual(null, d[2]);
  4558. }
  4559. #if !NET20
  4560. [Test]
  4561. public void SerializeHashSet()
  4562. {
  4563. string jsonText = JsonConvert.SerializeObject(new HashSet<string>()
  4564. {
  4565. "One",
  4566. "2",
  4567. "III"
  4568. }, Formatting.Indented);
  4569. Assert.AreEqual(@"[
  4570. ""One"",
  4571. ""2"",
  4572. ""III""
  4573. ]", jsonText);
  4574. HashSet<string> d = JsonConvert.DeserializeObject<HashSet<string>>(jsonText);
  4575. Assert.AreEqual(3, d.Count);
  4576. Assert.IsTrue(d.Contains("One"));
  4577. Assert.IsTrue(d.Contains("2"));
  4578. Assert.IsTrue(d.Contains("III"));
  4579. }
  4580. #endif
  4581. private class MyClass
  4582. {
  4583. public byte[] Prop1 { get; set; }
  4584. public MyClass()
  4585. {
  4586. Prop1 = new byte[0];
  4587. }
  4588. }
  4589. [Test]
  4590. public void DeserializeByteArray()
  4591. {
  4592. JsonSerializer serializer1 = new JsonSerializer();
  4593. serializer1.Converters.Add(new IsoDateTimeConverter());
  4594. serializer1.NullValueHandling = NullValueHandling.Ignore;
  4595. string json = @"[{""Prop1"":""""},{""Prop1"":""""}]";
  4596. JsonTextReader reader = new JsonTextReader(new StringReader(json));
  4597. MyClass[] z = (MyClass[])serializer1.Deserialize(reader, typeof(MyClass[]));
  4598. Assert.AreEqual(2, z.Length);
  4599. Assert.AreEqual(0, z[0].Prop1.Length);
  4600. Assert.AreEqual(0, z[1].Prop1.Length);
  4601. }
  4602. #if !NET20 && !NETFX_CORE
  4603. public class StringDictionaryTestClass
  4604. {
  4605. public StringDictionary StringDictionaryProperty { get; set; }
  4606. }
  4607. [Test]
  4608. public void StringDictionaryTest()
  4609. {
  4610. string classRef = typeof(StringDictionary).FullName;
  4611. StringDictionaryTestClass s1 = new StringDictionaryTestClass()
  4612. {
  4613. StringDictionaryProperty = new StringDictionary()
  4614. {
  4615. { "1", "One" },
  4616. { "2", "II" },
  4617. { "3", "3" }
  4618. }
  4619. };
  4620. string json = JsonConvert.SerializeObject(s1, Formatting.Indented);
  4621. ExceptionAssert.Throws<JsonSerializationException>(
  4622. "Cannot create and populate list type " + classRef + ". Path 'StringDictionaryProperty', line 2, position 32.",
  4623. () => { JsonConvert.DeserializeObject<StringDictionaryTestClass>(json); });
  4624. }
  4625. #endif
  4626. [JsonObject(MemberSerialization.OptIn)]
  4627. public struct StructWithAttribute
  4628. {
  4629. public string MyString { get; set; }
  4630. [JsonProperty]
  4631. public int MyInt { get; set; }
  4632. }
  4633. [Test]
  4634. public void SerializeStructWithJsonObjectAttribute()
  4635. {
  4636. StructWithAttribute testStruct = new StructWithAttribute
  4637. {
  4638. MyInt = int.MaxValue
  4639. };
  4640. string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented);
  4641. Assert.AreEqual(@"{
  4642. ""MyInt"": 2147483647
  4643. }", json);
  4644. StructWithAttribute newStruct = JsonConvert.DeserializeObject<StructWithAttribute>(json);
  4645. Assert.AreEqual(int.MaxValue, newStruct.MyInt);
  4646. }
  4647. public class TimeZoneOffsetObject
  4648. {
  4649. public DateTimeOffset Offset { get; set; }
  4650. }
  4651. #if !NET20
  4652. [Test]
  4653. public void ReadWriteTimeZoneOffsetIso()
  4654. {
  4655. var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject
  4656. {
  4657. Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6))
  4658. });
  4659. Assert.AreEqual("{\"Offset\":\"2000-01-01T00:00:00+06:00\"}", serializeObject);
  4660. JsonTextReader reader = new JsonTextReader(new StringReader(serializeObject));
  4661. reader.DateParseHandling = DateParseHandling.None;
  4662. JsonSerializer serializer = new JsonSerializer();
  4663. var deserializeObject = serializer.Deserialize<TimeZoneOffsetObject>(reader);
  4664. Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset);
  4665. Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date);
  4666. }
  4667. [Test]
  4668. public void DeserializePropertyNullableDateTimeOffsetExactIso()
  4669. {
  4670. NullableDateTimeTestClass d = JsonConvert.DeserializeObject<NullableDateTimeTestClass>("{\"DateTimeOffsetField\":\"2000-01-01T00:00:00+06:00\"}");
  4671. Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField);
  4672. }
  4673. [Test]
  4674. public void ReadWriteTimeZoneOffsetMsAjax()
  4675. {
  4676. var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject
  4677. {
  4678. Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6))
  4679. }, Formatting.None, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat });
  4680. Assert.AreEqual("{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}", serializeObject);
  4681. JsonTextReader reader = new JsonTextReader(new StringReader(serializeObject));
  4682. JsonSerializer serializer = new JsonSerializer();
  4683. serializer.DateParseHandling = DateParseHandling.None;
  4684. var deserializeObject = serializer.Deserialize<TimeZoneOffsetObject>(reader);
  4685. Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset);
  4686. Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date);
  4687. }
  4688. [Test]
  4689. public void DeserializePropertyNullableDateTimeOffsetExactMsAjax()
  4690. {
  4691. NullableDateTimeTestClass d = JsonConvert.DeserializeObject<NullableDateTimeTestClass>("{\"DateTimeOffsetField\":\"\\/Date(946663200000+0600)\\/\"}");
  4692. Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField);
  4693. }
  4694. #endif
  4695. public abstract class LogEvent
  4696. {
  4697. [JsonProperty("event")]
  4698. public abstract string EventName { get; }
  4699. }
  4700. public class DerivedEvent : LogEvent
  4701. {
  4702. public override string EventName
  4703. {
  4704. get { return "derived"; }
  4705. }
  4706. }
  4707. [Test]
  4708. public void OverridenPropertyMembers()
  4709. {
  4710. string json = JsonConvert.SerializeObject(new DerivedEvent(), Formatting.Indented);
  4711. Assert.AreEqual(@"{
  4712. ""event"": ""derived""
  4713. }", json);
  4714. }
  4715. #if !(NET35 || NET20 || PORTABLE40)
  4716. [Test]
  4717. public void SerializeExpandoObject()
  4718. {
  4719. dynamic expando = new ExpandoObject();
  4720. expando.Int = 1;
  4721. expando.Decimal = 99.9d;
  4722. expando.Complex = new ExpandoObject();
  4723. expando.Complex.String = "I am a string";
  4724. expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc);
  4725. string json = JsonConvert.SerializeObject(expando, Formatting.Indented);
  4726. Assert.AreEqual(@"{
  4727. ""Int"": 1,
  4728. ""Decimal"": 99.9,
  4729. ""Complex"": {
  4730. ""String"": ""I am a string"",
  4731. ""DateTime"": ""2000-12-20T18:55:00Z""
  4732. }
  4733. }", json);
  4734. IDictionary<string, object> newExpando = JsonConvert.DeserializeObject<ExpandoObject>(json);
  4735. CustomAssert.IsInstanceOfType(typeof(long), newExpando["Int"]);
  4736. Assert.AreEqual((long)expando.Int, newExpando["Int"]);
  4737. CustomAssert.IsInstanceOfType(typeof(double), newExpando["Decimal"]);
  4738. Assert.AreEqual(expando.Decimal, newExpando["Decimal"]);
  4739. CustomAssert.IsInstanceOfType(typeof(ExpandoObject), newExpando["Complex"]);
  4740. IDictionary<string, object> o = (ExpandoObject)newExpando["Complex"];
  4741. CustomAssert.IsInstanceOfType(typeof(string), o["String"]);
  4742. Assert.AreEqual(expando.Complex.String, o["String"]);
  4743. CustomAssert.IsInstanceOfType(typeof(DateTime), o["DateTime"]);
  4744. Assert.AreEqual(expando.Complex.DateTime, o["DateTime"]);
  4745. }
  4746. #endif
  4747. [Test]
  4748. public void DeserializeDecimalExact()
  4749. {
  4750. decimal d = JsonConvert.DeserializeObject<decimal>("123456789876543.21");
  4751. Assert.AreEqual(123456789876543.21m, d);
  4752. }
  4753. [Test]
  4754. public void DeserializeNullableDecimalExact()
  4755. {
  4756. decimal? d = JsonConvert.DeserializeObject<decimal?>("123456789876543.21");
  4757. Assert.AreEqual(123456789876543.21m, d);
  4758. }
  4759. [Test]
  4760. public void DeserializeDecimalPropertyExact()
  4761. {
  4762. string json = "{Amount:123456789876543.21}";
  4763. JsonTextReader reader = new JsonTextReader(new StringReader(json));
  4764. reader.FloatParseHandling = FloatParseHandling.Decimal;
  4765. JsonSerializer serializer = new JsonSerializer();
  4766. Invoice i = serializer.Deserialize<Invoice>(reader);
  4767. Assert.AreEqual(123456789876543.21m, i.Amount);
  4768. }
  4769. [Test]
  4770. public void DeserializeDecimalArrayExact()
  4771. {
  4772. string json = "[123456789876543.21]";
  4773. IList<decimal> a = JsonConvert.DeserializeObject<IList<decimal>>(json);
  4774. Assert.AreEqual(123456789876543.21m, a[0]);
  4775. }
  4776. [Test]
  4777. public void DeserializeDecimalDictionaryExact()
  4778. {
  4779. string json = "{'Value':123456789876543.21}";
  4780. JsonTextReader reader = new JsonTextReader(new StringReader(json));
  4781. reader.FloatParseHandling = FloatParseHandling.Decimal;
  4782. JsonSerializer serializer = new JsonSerializer();
  4783. IDictionary<string, decimal> d = serializer.Deserialize<IDictionary<string, decimal>>(reader);
  4784. Assert.AreEqual(123456789876543.21m, d["Value"]);
  4785. }
  4786. public struct Vector
  4787. {
  4788. public float X;
  4789. public float Y;
  4790. public float Z;
  4791. public override string ToString()
  4792. {
  4793. return string.Format("({0},{1},{2})", X, Y, Z);
  4794. }
  4795. }
  4796. public class VectorParent
  4797. {
  4798. public Vector Position;
  4799. }
  4800. [Test]
  4801. public void DeserializeStructProperty()
  4802. {
  4803. VectorParent obj = new VectorParent();
  4804. obj.Position = new Vector { X = 1, Y = 2, Z = 3 };
  4805. string str = JsonConvert.SerializeObject(obj);
  4806. obj = JsonConvert.DeserializeObject<VectorParent>(str);
  4807. Assert.AreEqual(1, obj.Position.X);
  4808. Assert.AreEqual(2, obj.Position.Y);
  4809. Assert.AreEqual(3, obj.Position.Z);
  4810. }
  4811. [JsonObject(MemberSerialization.OptIn)]
  4812. public class Derived : Base
  4813. {
  4814. [JsonProperty]
  4815. public string IDoWork { get; private set; }
  4816. private Derived()
  4817. {
  4818. }
  4819. internal Derived(string dontWork, string doWork)
  4820. : base(dontWork)
  4821. {
  4822. IDoWork = doWork;
  4823. }
  4824. }
  4825. [JsonObject(MemberSerialization.OptIn)]
  4826. public class Base
  4827. {
  4828. [JsonProperty]
  4829. public string IDontWork { get; private set; }
  4830. protected Base()
  4831. {
  4832. }
  4833. internal Base(string dontWork)
  4834. {
  4835. IDontWork = dontWork;
  4836. }
  4837. }
  4838. [Test]
  4839. public void PrivateSetterOnBaseClassProperty()
  4840. {
  4841. var derived = new Derived("meh", "woo");
  4842. var settings = new JsonSerializerSettings
  4843. {
  4844. TypeNameHandling = TypeNameHandling.Objects,
  4845. ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
  4846. };
  4847. string json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings);
  4848. var meh = JsonConvert.DeserializeObject<Base>(json, settings);
  4849. Assert.AreEqual(((Derived)meh).IDoWork, "woo");
  4850. Assert.AreEqual(meh.IDontWork, "meh");
  4851. }
  4852. #if !(NET20 || NETFX_CORE)
  4853. [DataContract]
  4854. public struct StructISerializable : ISerializable
  4855. {
  4856. private string _name;
  4857. public StructISerializable(SerializationInfo info, StreamingContext context)
  4858. {
  4859. _name = info.GetString("Name");
  4860. }
  4861. [DataMember]
  4862. public string Name
  4863. {
  4864. get { return _name; }
  4865. set { _name = value; }
  4866. }
  4867. public void GetObjectData(SerializationInfo info, StreamingContext context)
  4868. {
  4869. info.AddValue("Name", _name);
  4870. }
  4871. }
  4872. [DataContract]
  4873. public class NullableStructPropertyClass
  4874. {
  4875. private StructISerializable _foo1;
  4876. private StructISerializable? _foo2;
  4877. [DataMember]
  4878. public StructISerializable Foo1
  4879. {
  4880. get { return _foo1; }
  4881. set { _foo1 = value; }
  4882. }
  4883. [DataMember]
  4884. public StructISerializable? Foo2
  4885. {
  4886. get { return _foo2; }
  4887. set { _foo2 = value; }
  4888. }
  4889. }
  4890. [Test]
  4891. public void DeserializeNullableStruct()
  4892. {
  4893. NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass();
  4894. nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" };
  4895. nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" };
  4896. NullableStructPropertyClass barWithNull = new NullableStructPropertyClass();
  4897. barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" };
  4898. barWithNull.Foo2 = null;
  4899. //throws error on deserialization because bar1.Foo2 is of type Foo?
  4900. string s = JsonConvert.SerializeObject(nullableStructPropertyClass);
  4901. NullableStructPropertyClass deserialized = deserialize(s);
  4902. Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
  4903. Assert.AreEqual(deserialized.Foo2.Value.Name, "foo 2");
  4904. //no error Foo2 is null
  4905. s = JsonConvert.SerializeObject(barWithNull);
  4906. deserialized = deserialize(s);
  4907. Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
  4908. Assert.AreEqual(deserialized.Foo2, null);
  4909. }
  4910. private static NullableStructPropertyClass deserialize(string serStr)
  4911. {
  4912. return JsonConvert.DeserializeObject<NullableStructPropertyClass>(
  4913. serStr,
  4914. new JsonSerializerSettings
  4915. {
  4916. NullValueHandling = NullValueHandling.Ignore,
  4917. MissingMemberHandling = MissingMemberHandling.Ignore
  4918. });
  4919. }
  4920. #endif
  4921. public class Response
  4922. {
  4923. public string Name { get; set; }
  4924. public JToken Data { get; set; }
  4925. }
  4926. [Test]
  4927. public void DeserializeJToken()
  4928. {
  4929. Response response = new Response
  4930. {
  4931. Name = "Success",
  4932. Data = new JObject(new JProperty("First", "Value1"), new JProperty("Second", "Value2"))
  4933. };
  4934. string json = JsonConvert.SerializeObject(response, Formatting.Indented);
  4935. Response deserializedResponse = JsonConvert.DeserializeObject<Response>(json);
  4936. Assert.AreEqual("Success", deserializedResponse.Name);
  4937. Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data));
  4938. }
  4939. public abstract class Test<T>
  4940. {
  4941. public abstract T Value { get; set; }
  4942. }
  4943. [JsonObject(MemberSerialization.OptIn)]
  4944. public class DecimalTest : Test<decimal>
  4945. {
  4946. protected DecimalTest()
  4947. {
  4948. }
  4949. public DecimalTest(decimal val)
  4950. {
  4951. Value = val;
  4952. }
  4953. [JsonProperty]
  4954. public override decimal Value { get; set; }
  4955. }
  4956. [Test]
  4957. public void DeserializeMinValueDecimal()
  4958. {
  4959. var data = new DecimalTest(decimal.MinValue);
  4960. var json = JsonConvert.SerializeObject(data);
  4961. var obj = JsonConvert.DeserializeObject<DecimalTest>(json, new JsonSerializerSettings { SpecialPropertyHandling = SpecialPropertyHandling.Default });
  4962. Assert.AreEqual(decimal.MinValue, obj.Value);
  4963. }
  4964. public class NonPublicConstructorWithJsonConstructor
  4965. {
  4966. public string Value { get; private set; }
  4967. public string Constructor { get; private set; }
  4968. [JsonConstructor]
  4969. private NonPublicConstructorWithJsonConstructor()
  4970. {
  4971. Constructor = "NonPublic";
  4972. }
  4973. public NonPublicConstructorWithJsonConstructor(string value)
  4974. {
  4975. Value = value;
  4976. Constructor = "Public Paramatized";
  4977. }
  4978. }
  4979. [Test]
  4980. public void NonPublicConstructorWithJsonConstructorTest()
  4981. {
  4982. NonPublicConstructorWithJsonConstructor c = JsonConvert.DeserializeObject<NonPublicConstructorWithJsonConstructor>("{}");
  4983. Assert.AreEqual("NonPublic", c.Constructor);
  4984. }
  4985. public class PublicConstructorOverridenByJsonConstructor
  4986. {
  4987. public string Value { get; private set; }
  4988. public string Constructor { get; private set; }
  4989. public PublicConstructorOverridenByJsonConstructor()
  4990. {
  4991. Constructor = "NonPublic";
  4992. }
  4993. [JsonConstructor]
  4994. public PublicConstructorOverridenByJsonConstructor(string value)
  4995. {
  4996. Value = value;
  4997. Constructor = "Public Paramatized";
  4998. }
  4999. }
  5000. [Test]
  5001. public void PublicConstructorOverridenByJsonConstructorTest()
  5002. {
  5003. PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject<PublicConstructorOverridenByJsonConstructor>("{Value:'value!'}");
  5004. Assert.AreEqual("Public Paramatized", c.Constructor);
  5005. Assert.AreEqual("value!", c.Value);
  5006. }
  5007. public class MultipleParamatrizedConstructorsJsonConstructor
  5008. {
  5009. public string Value { get; private set; }
  5010. public int Age { get; private set; }
  5011. public string Constructor { get; private set; }
  5012. public MultipleParamatrizedConstructorsJsonConstructor(string value)
  5013. {
  5014. Value = value;
  5015. Constructor = "Public Paramatized 1";
  5016. }
  5017. [JsonConstructor]
  5018. public MultipleParamatrizedConstructorsJsonConstructor(string value, int age)
  5019. {
  5020. Value = value;
  5021. Age = age;
  5022. Constructor = "Public Paramatized 2";
  5023. }
  5024. }
  5025. [Test]
  5026. public void MultipleParamatrizedConstructorsJsonConstructorTest()
  5027. {
  5028. MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject<MultipleParamatrizedConstructorsJsonConstructor>("{Value:'value!', Age:1}");
  5029. Assert.AreEqual("Public Paramatized 2", c.Constructor);
  5030. Assert.AreEqual("value!", c.Value);
  5031. Assert.AreEqual(1, c.Age);
  5032. }
  5033. public class EnumerableClass
  5034. {
  5035. public IEnumerable<string> Enumerable { get; set; }
  5036. }
  5037. [Test]
  5038. public void DeserializeEnumerable()
  5039. {
  5040. EnumerableClass c = new EnumerableClass
  5041. {
  5042. Enumerable = new List<string> { "One", "Two", "Three" }
  5043. };
  5044. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  5045. Assert.AreEqual(@"{
  5046. ""Enumerable"": [
  5047. ""One"",
  5048. ""Two"",
  5049. ""Three""
  5050. ]
  5051. }", json);
  5052. EnumerableClass c2 = JsonConvert.DeserializeObject<EnumerableClass>(json);
  5053. Assert.AreEqual("One", c2.Enumerable.ElementAt(0));
  5054. Assert.AreEqual("Two", c2.Enumerable.ElementAt(1));
  5055. Assert.AreEqual("Three", c2.Enumerable.ElementAt(2));
  5056. }
  5057. [JsonObject(MemberSerialization.OptIn)]
  5058. public class ItemBase
  5059. {
  5060. [JsonProperty]
  5061. public string Name { get; set; }
  5062. }
  5063. public class ComplexItem : ItemBase
  5064. {
  5065. public Stream Source { get; set; }
  5066. }
  5067. [Test]
  5068. public void SerializeAttributesOnBase()
  5069. {
  5070. ComplexItem i = new ComplexItem();
  5071. string json = JsonConvert.SerializeObject(i, Formatting.Indented);
  5072. Assert.AreEqual(@"{
  5073. ""Name"": null
  5074. }", json);
  5075. }
  5076. public class DeserializeStringConvert
  5077. {
  5078. public string Name { get; set; }
  5079. public int Age { get; set; }
  5080. public double Height { get; set; }
  5081. public decimal Price { get; set; }
  5082. }
  5083. [Test]
  5084. public void DeserializeStringEnglish()
  5085. {
  5086. string json = @"{
  5087. 'Name': 'James Hughes',
  5088. 'Age': '40',
  5089. 'Height': '44.4',
  5090. 'Price': '4'
  5091. }";
  5092. DeserializeStringConvert p = JsonConvert.DeserializeObject<DeserializeStringConvert>(json);
  5093. Assert.AreEqual(40, p.Age);
  5094. Assert.AreEqual(44.4, p.Height);
  5095. Assert.AreEqual(4m, p.Price);
  5096. }
  5097. [Test]
  5098. public void DeserializeNullDateTimeValueTest()
  5099. {
  5100. ExceptionAssert.Throws<JsonSerializationException>(
  5101. "Error converting value {null} to type 'System.DateTime'. Path '', line 1, position 4.",
  5102. () => { JsonConvert.DeserializeObject("null", typeof(DateTime)); });
  5103. }
  5104. [Test]
  5105. public void DeserializeNullNullableDateTimeValueTest()
  5106. {
  5107. object dateTime = JsonConvert.DeserializeObject("null", typeof(DateTime?));
  5108. Assert.IsNull(dateTime);
  5109. }
  5110. [Test]
  5111. public void MultiIndexSuperTest()
  5112. {
  5113. MultiIndexSuper e = new MultiIndexSuper();
  5114. string json = JsonConvert.SerializeObject(e, Formatting.Indented);
  5115. Assert.AreEqual(@"{}", json);
  5116. }
  5117. public class MultiIndexSuper : MultiIndexBase
  5118. {
  5119. }
  5120. public abstract class MultiIndexBase
  5121. {
  5122. protected internal object this[string propertyName]
  5123. {
  5124. get { return null; }
  5125. set { }
  5126. }
  5127. protected internal object this[object property]
  5128. {
  5129. get { return null; }
  5130. set { }
  5131. }
  5132. }
  5133. public class CommentTestClass
  5134. {
  5135. public bool Indexed { get; set; }
  5136. public int StartYear { get; set; }
  5137. public IList<decimal> Values { get; set; }
  5138. }
  5139. [Test]
  5140. public void CommentTestClassTest()
  5141. {
  5142. string json = @"{""indexed"":true, ""startYear"":1939, ""values"":
  5143. [ 3000, /* 1940-1949 */
  5144. 3000, 3600, 3600, 3600, 3600, 4200, 4200, 4200, 4200, 4800, /* 1950-1959 */
  5145. 4800, 4800, 4800, 4800, 4800, 4800, 6600, 6600, 7800, 7800, /* 1960-1969 */
  5146. 7800, 7800, 9000, 10800, 13200, 14100, 15300, 16500, 17700, 22900, /* 1970-1979 */
  5147. 25900, 29700, 32400, 35700, 37800, 39600, 42000, 43800, 45000, 48000, /* 1980-1989 */
  5148. 51300, 53400, 55500, 57600, 60600, 61200, 62700, 65400, 68400, 72600, /* 1990-1999 */
  5149. 76200, 80400, 84900, 87000, 87900, 90000, 94200, 97500, 102000, 106800, /* 2000-2009 */
  5150. 106800, 106800] /* 2010-2011 */
  5151. }";
  5152. CommentTestClass commentTestClass = JsonConvert.DeserializeObject<CommentTestClass>(json);
  5153. Assert.AreEqual(true, commentTestClass.Indexed);
  5154. Assert.AreEqual(1939, commentTestClass.StartYear);
  5155. Assert.AreEqual(63, commentTestClass.Values.Count);
  5156. }
  5157. private class DTOWithParameterisedConstructor
  5158. {
  5159. public DTOWithParameterisedConstructor(string A)
  5160. {
  5161. this.A = A;
  5162. B = 2;
  5163. }
  5164. public string A { get; set; }
  5165. public int? B { get; set; }
  5166. }
  5167. private class DTOWithoutParameterisedConstructor
  5168. {
  5169. public DTOWithoutParameterisedConstructor()
  5170. {
  5171. B = 2;
  5172. }
  5173. public string A { get; set; }
  5174. public int? B { get; set; }
  5175. }
  5176. [Test]
  5177. public void PopulationBehaviourForOmittedPropertiesIsTheSameForParameterisedConstructorAsForDefaultConstructor()
  5178. {
  5179. string json = @"{A:""Test""}";
  5180. var withoutParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithoutParameterisedConstructor>(json);
  5181. var withParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithParameterisedConstructor>(json);
  5182. Assert.AreEqual(withoutParameterisedConstructor.B, withParameterisedConstructor.B);
  5183. }
  5184. public class EnumerableArrayPropertyClass
  5185. {
  5186. public IEnumerable<int> Numbers
  5187. {
  5188. get
  5189. {
  5190. return new[] { 1, 2, 3 }; //fails
  5191. //return new List<int>(new[] { 1, 2, 3 }); //works
  5192. }
  5193. }
  5194. }
  5195. [Test]
  5196. public void SkipPopulatingArrayPropertyClass()
  5197. {
  5198. string json = JsonConvert.SerializeObject(new EnumerableArrayPropertyClass());
  5199. JsonConvert.DeserializeObject<EnumerableArrayPropertyClass>(json);
  5200. }
  5201. #if !(NET20)
  5202. [DataContract]
  5203. public class BaseDataContract
  5204. {
  5205. [DataMember(Name = "virtualMember")]
  5206. public virtual string VirtualMember { get; set; }
  5207. [DataMember(Name = "nonVirtualMember")]
  5208. public string NonVirtualMember { get; set; }
  5209. }
  5210. public class ChildDataContract : BaseDataContract
  5211. {
  5212. public override string VirtualMember { get; set; }
  5213. public string NewMember { get; set; }
  5214. }
  5215. [Test]
  5216. public void ChildDataContractTest()
  5217. {
  5218. ChildDataContract cc = new ChildDataContract
  5219. {
  5220. VirtualMember = "VirtualMember!",
  5221. NonVirtualMember = "NonVirtualMember!"
  5222. };
  5223. string result = JsonConvert.SerializeObject(cc, Formatting.Indented);
  5224. // Assert.AreEqual(@"{
  5225. // ""VirtualMember"": ""VirtualMember!"",
  5226. // ""NewMember"": null,
  5227. // ""nonVirtualMember"": ""NonVirtualMember!""
  5228. //}", result);
  5229. Console.WriteLine(result);
  5230. }
  5231. [Test]
  5232. public void ChildDataContractTestWithDataContractSerializer()
  5233. {
  5234. ChildDataContract cc = new ChildDataContract
  5235. {
  5236. VirtualMember = "VirtualMember!",
  5237. NonVirtualMember = "NonVirtualMember!"
  5238. };
  5239. DataContractSerializer serializer = new DataContractSerializer(typeof(ChildDataContract));
  5240. MemoryStream ms = new MemoryStream();
  5241. serializer.WriteObject(ms, cc);
  5242. string xml = Encoding.UTF8.GetString(ms.ToArray(), 0, Convert.ToInt32(ms.Length));
  5243. Console.WriteLine(xml);
  5244. }
  5245. #endif
  5246. [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
  5247. public class BaseObject
  5248. {
  5249. [JsonProperty(PropertyName = "virtualMember")]
  5250. public virtual string VirtualMember { get; set; }
  5251. [JsonProperty(PropertyName = "nonVirtualMember")]
  5252. public string NonVirtualMember { get; set; }
  5253. }
  5254. public class ChildObject : BaseObject
  5255. {
  5256. public override string VirtualMember { get; set; }
  5257. public string NewMember { get; set; }
  5258. }
  5259. public class ChildWithDifferentOverrideObject : BaseObject
  5260. {
  5261. [JsonProperty(PropertyName = "differentVirtualMember")]
  5262. public override string VirtualMember { get; set; }
  5263. }
  5264. [Test]
  5265. public void ChildObjectTest()
  5266. {
  5267. ChildObject cc = new ChildObject
  5268. {
  5269. VirtualMember = "VirtualMember!",
  5270. NonVirtualMember = "NonVirtualMember!"
  5271. };
  5272. string result = JsonConvert.SerializeObject(cc);
  5273. Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
  5274. }
  5275. [Test]
  5276. public void ChildWithDifferentOverrideObjectTest()
  5277. {
  5278. ChildWithDifferentOverrideObject cc = new ChildWithDifferentOverrideObject
  5279. {
  5280. VirtualMember = "VirtualMember!",
  5281. NonVirtualMember = "NonVirtualMember!"
  5282. };
  5283. string result = JsonConvert.SerializeObject(cc);
  5284. Console.WriteLine(result);
  5285. Assert.AreEqual(@"{""differentVirtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
  5286. }
  5287. [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
  5288. public interface IInterfaceObject
  5289. {
  5290. [JsonProperty(PropertyName = "virtualMember")]
  5291. [JsonConverter(typeof(IsoDateTimeConverter))]
  5292. DateTime InterfaceMember { get; set; }
  5293. }
  5294. public class ImplementInterfaceObject : IInterfaceObject
  5295. {
  5296. public DateTime InterfaceMember { get; set; }
  5297. public string NewMember { get; set; }
  5298. [JsonProperty(PropertyName = "newMemberWithProperty")]
  5299. public string NewMemberWithProperty { get; set; }
  5300. }
  5301. [Test]
  5302. public void ImplementInterfaceObjectTest()
  5303. {
  5304. ImplementInterfaceObject cc = new ImplementInterfaceObject
  5305. {
  5306. InterfaceMember = new DateTime(2010, 12, 31, 0, 0, 0, DateTimeKind.Utc),
  5307. NewMember = "NewMember!"
  5308. };
  5309. string result = JsonConvert.SerializeObject(cc, Formatting.Indented);
  5310. Assert.AreEqual(@"{
  5311. ""virtualMember"": ""2010-12-31T00:00:00Z"",
  5312. ""newMemberWithProperty"": null
  5313. }", result);
  5314. }
  5315. public class NonDefaultConstructorWithReadOnlyCollectionProperty
  5316. {
  5317. public string Title { get; set; }
  5318. public IList<string> Categories { get; private set; }
  5319. public NonDefaultConstructorWithReadOnlyCollectionProperty(string title)
  5320. {
  5321. Title = title;
  5322. Categories = new List<string>();
  5323. }
  5324. }
  5325. [Test]
  5326. public void NonDefaultConstructorWithReadOnlyCollectionPropertyTest()
  5327. {
  5328. NonDefaultConstructorWithReadOnlyCollectionProperty c1 = new NonDefaultConstructorWithReadOnlyCollectionProperty("blah");
  5329. c1.Categories.Add("one");
  5330. c1.Categories.Add("two");
  5331. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  5332. Assert.AreEqual(@"{
  5333. ""Title"": ""blah"",
  5334. ""Categories"": [
  5335. ""one"",
  5336. ""two""
  5337. ]
  5338. }", json);
  5339. NonDefaultConstructorWithReadOnlyCollectionProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyCollectionProperty>(json);
  5340. Assert.AreEqual(c1.Title, c2.Title);
  5341. Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
  5342. Assert.AreEqual("one", c2.Categories[0]);
  5343. Assert.AreEqual("two", c2.Categories[1]);
  5344. }
  5345. public class NonDefaultConstructorWithReadOnlyDictionaryProperty
  5346. {
  5347. public string Title { get; set; }
  5348. public IDictionary<string, int> Categories { get; private set; }
  5349. public NonDefaultConstructorWithReadOnlyDictionaryProperty(string title)
  5350. {
  5351. Title = title;
  5352. Categories = new Dictionary<string, int>();
  5353. }
  5354. }
  5355. [Test]
  5356. public void NonDefaultConstructorWithReadOnlyDictionaryPropertyTest()
  5357. {
  5358. NonDefaultConstructorWithReadOnlyDictionaryProperty c1 = new NonDefaultConstructorWithReadOnlyDictionaryProperty("blah");
  5359. c1.Categories.Add("one", 1);
  5360. c1.Categories.Add("two", 2);
  5361. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  5362. Assert.AreEqual(@"{
  5363. ""Title"": ""blah"",
  5364. ""Categories"": {
  5365. ""one"": 1,
  5366. ""two"": 2
  5367. }
  5368. }", json);
  5369. NonDefaultConstructorWithReadOnlyDictionaryProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyDictionaryProperty>(json);
  5370. Assert.AreEqual(c1.Title, c2.Title);
  5371. Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
  5372. Assert.AreEqual(1, c2.Categories["one"]);
  5373. Assert.AreEqual(2, c2.Categories["two"]);
  5374. }
  5375. [JsonObject(MemberSerialization.OptIn)]
  5376. public class ClassAttributeBase
  5377. {
  5378. [JsonProperty]
  5379. public string BaseClassValue { get; set; }
  5380. }
  5381. public class ClassAttributeDerived : ClassAttributeBase
  5382. {
  5383. [JsonProperty]
  5384. public string DerivedClassValue { get; set; }
  5385. public string NonSerialized { get; set; }
  5386. }
  5387. public class CollectionClassAttributeDerived : ClassAttributeBase, ICollection<object>
  5388. {
  5389. [JsonProperty]
  5390. public string CollectionDerivedClassValue { get; set; }
  5391. public void Add(object item)
  5392. {
  5393. throw new NotImplementedException();
  5394. }
  5395. public void Clear()
  5396. {
  5397. throw new NotImplementedException();
  5398. }
  5399. public bool Contains(object item)
  5400. {
  5401. throw new NotImplementedException();
  5402. }
  5403. public void CopyTo(object[] array, int arrayIndex)
  5404. {
  5405. throw new NotImplementedException();
  5406. }
  5407. public int Count
  5408. {
  5409. get { throw new NotImplementedException(); }
  5410. }
  5411. public bool IsReadOnly
  5412. {
  5413. get { throw new NotImplementedException(); }
  5414. }
  5415. public bool Remove(object item)
  5416. {
  5417. throw new NotImplementedException();
  5418. }
  5419. public IEnumerator<object> GetEnumerator()
  5420. {
  5421. throw new NotImplementedException();
  5422. }
  5423. IEnumerator IEnumerable.GetEnumerator()
  5424. {
  5425. throw new NotImplementedException();
  5426. }
  5427. }
  5428. [Test]
  5429. public void ClassAttributesInheritance()
  5430. {
  5431. string json = JsonConvert.SerializeObject(new ClassAttributeDerived
  5432. {
  5433. BaseClassValue = "BaseClassValue!",
  5434. DerivedClassValue = "DerivedClassValue!",
  5435. NonSerialized = "NonSerialized!"
  5436. }, Formatting.Indented);
  5437. Assert.AreEqual(@"{
  5438. ""DerivedClassValue"": ""DerivedClassValue!"",
  5439. ""BaseClassValue"": ""BaseClassValue!""
  5440. }", json);
  5441. json = JsonConvert.SerializeObject(new CollectionClassAttributeDerived
  5442. {
  5443. BaseClassValue = "BaseClassValue!",
  5444. CollectionDerivedClassValue = "CollectionDerivedClassValue!"
  5445. }, Formatting.Indented);
  5446. Assert.AreEqual(@"{
  5447. ""CollectionDerivedClassValue"": ""CollectionDerivedClassValue!"",
  5448. ""BaseClassValue"": ""BaseClassValue!""
  5449. }", json);
  5450. }
  5451. public class PrivateMembersClassWithAttributes
  5452. {
  5453. public PrivateMembersClassWithAttributes(string privateString, string internalString, string readonlyString)
  5454. {
  5455. _privateString = privateString;
  5456. _readonlyString = readonlyString;
  5457. _internalString = internalString;
  5458. }
  5459. public PrivateMembersClassWithAttributes()
  5460. {
  5461. _readonlyString = "default!";
  5462. }
  5463. [JsonProperty]
  5464. private string _privateString;
  5465. [JsonProperty]
  5466. private readonly string _readonlyString;
  5467. [JsonProperty]
  5468. internal string _internalString;
  5469. public string UseValue()
  5470. {
  5471. return _readonlyString;
  5472. }
  5473. }
  5474. [Test]
  5475. public void PrivateMembersClassWithAttributesTest()
  5476. {
  5477. PrivateMembersClassWithAttributes c1 = new PrivateMembersClassWithAttributes("privateString!", "internalString!", "readonlyString!");
  5478. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  5479. Assert.AreEqual(@"{
  5480. ""_privateString"": ""privateString!"",
  5481. ""_readonlyString"": ""readonlyString!"",
  5482. ""_internalString"": ""internalString!""
  5483. }", json);
  5484. PrivateMembersClassWithAttributes c2 = JsonConvert.DeserializeObject<PrivateMembersClassWithAttributes>(json);
  5485. Assert.AreEqual("readonlyString!", c2.UseValue());
  5486. }
  5487. public partial class BusRun
  5488. {
  5489. public IEnumerable<Nullable<DateTime>> Departures { get; set; }
  5490. public Boolean WheelchairAccessible { get; set; }
  5491. }
  5492. [Test]
  5493. public void DeserializeGenericEnumerableProperty()
  5494. {
  5495. BusRun r = JsonConvert.DeserializeObject<BusRun>("{\"Departures\":[\"\\/Date(1309874148734-0400)\\/\",\"\\/Date(1309874148739-0400)\\/\",null],\"WheelchairAccessible\":true}");
  5496. Assert.AreEqual(typeof(List<DateTime?>), r.Departures.GetType());
  5497. Assert.AreEqual(3, r.Departures.Count());
  5498. Assert.IsNotNull(r.Departures.ElementAt(0));
  5499. Assert.IsNotNull(r.Departures.ElementAt(1));
  5500. Assert.IsNull(r.Departures.ElementAt(2));
  5501. }
  5502. #if !(NET20)
  5503. [DataContract]
  5504. public class BaseType
  5505. {
  5506. [DataMember]
  5507. public string zebra;
  5508. }
  5509. [DataContract]
  5510. public class DerivedType : BaseType
  5511. {
  5512. [DataMember(Order = 0)]
  5513. public string bird;
  5514. [DataMember(Order = 1)]
  5515. public string parrot;
  5516. [DataMember]
  5517. public string dog;
  5518. [DataMember(Order = 3)]
  5519. public string antelope;
  5520. [DataMember]
  5521. public string cat;
  5522. [JsonProperty(Order = 1)]
  5523. public string albatross;
  5524. [JsonProperty(Order = -2)]
  5525. public string dinosaur;
  5526. }
  5527. [Test]
  5528. public void JsonPropertyDataMemberOrder()
  5529. {
  5530. DerivedType d = new DerivedType();
  5531. string json = JsonConvert.SerializeObject(d, Formatting.Indented);
  5532. Assert.AreEqual(@"{
  5533. ""dinosaur"": null,
  5534. ""dog"": null,
  5535. ""cat"": null,
  5536. ""zebra"": null,
  5537. ""bird"": null,
  5538. ""parrot"": null,
  5539. ""albatross"": null,
  5540. ""antelope"": null
  5541. }", json);
  5542. }
  5543. #endif
  5544. public class ClassWithException
  5545. {
  5546. public IList<Exception> Exceptions { get; set; }
  5547. public ClassWithException()
  5548. {
  5549. Exceptions = new List<Exception>();
  5550. }
  5551. }
  5552. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  5553. [Test]
  5554. public void SerializeException1()
  5555. {
  5556. ClassWithException classWithException = new ClassWithException();
  5557. try
  5558. {
  5559. throw new Exception("Test Exception");
  5560. }
  5561. catch (Exception ex)
  5562. {
  5563. classWithException.Exceptions.Add(ex);
  5564. }
  5565. string sex = JsonConvert.SerializeObject(classWithException);
  5566. ClassWithException dex = JsonConvert.DeserializeObject<ClassWithException>(sex);
  5567. Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString());
  5568. sex = JsonConvert.SerializeObject(classWithException, Formatting.Indented);
  5569. dex = JsonConvert.DeserializeObject<ClassWithException>(sex); // this fails!
  5570. Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString());
  5571. }
  5572. #endif
  5573. public void DeserializeIDictionary()
  5574. {
  5575. IDictionary dictionary = JsonConvert.DeserializeObject<IDictionary>("{'name':'value!'}");
  5576. Assert.AreEqual(1, dictionary.Count);
  5577. Assert.AreEqual("value!", dictionary["name"]);
  5578. }
  5579. public void DeserializeIList()
  5580. {
  5581. IList list = JsonConvert.DeserializeObject<IList>("['1', 'two', 'III']");
  5582. Assert.AreEqual(3, list.Count);
  5583. }
  5584. public void UriGuidTimeSpanTestClassEmptyTest()
  5585. {
  5586. UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass();
  5587. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  5588. Assert.AreEqual(@"{
  5589. ""Guid"": ""00000000-0000-0000-0000-000000000000"",
  5590. ""NullableGuid"": null,
  5591. ""TimeSpan"": ""00:00:00"",
  5592. ""NullableTimeSpan"": null,
  5593. ""Uri"": null
  5594. }", json);
  5595. UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject<UriGuidTimeSpanTestClass>(json);
  5596. Assert.AreEqual(c1.Guid, c2.Guid);
  5597. Assert.AreEqual(c1.NullableGuid, c2.NullableGuid);
  5598. Assert.AreEqual(c1.TimeSpan, c2.TimeSpan);
  5599. Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
  5600. Assert.AreEqual(c1.Uri, c2.Uri);
  5601. }
  5602. public void UriGuidTimeSpanTestClassValuesTest()
  5603. {
  5604. UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass
  5605. {
  5606. Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"),
  5607. NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"),
  5608. TimeSpan = TimeSpan.FromDays(1),
  5609. NullableTimeSpan = TimeSpan.FromHours(1),
  5610. Uri = new Uri("http://testuri.com")
  5611. };
  5612. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  5613. Assert.AreEqual(@"{
  5614. ""Guid"": ""1924129c-f7e0-40f3-9607-9939c531395a"",
  5615. ""NullableGuid"": ""9e9f3adf-e017-4f72-91e0-617ebe85967d"",
  5616. ""TimeSpan"": ""1.00:00:00"",
  5617. ""NullableTimeSpan"": ""01:00:00"",
  5618. ""Uri"": ""http://testuri.com/""
  5619. }", json);
  5620. UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject<UriGuidTimeSpanTestClass>(json);
  5621. Assert.AreEqual(c1.Guid, c2.Guid);
  5622. Assert.AreEqual(c1.NullableGuid, c2.NullableGuid);
  5623. Assert.AreEqual(c1.TimeSpan, c2.TimeSpan);
  5624. Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
  5625. Assert.AreEqual(c1.Uri, c2.Uri);
  5626. }
  5627. [Test]
  5628. public void NullableValueGenericDictionary()
  5629. {
  5630. IDictionary<string, int?> v1 = new Dictionary<string, int?>
  5631. {
  5632. { "First", 1 },
  5633. { "Second", null },
  5634. { "Third", 3 }
  5635. };
  5636. string json = JsonConvert.SerializeObject(v1, Formatting.Indented);
  5637. Assert.AreEqual(@"{
  5638. ""First"": 1,
  5639. ""Second"": null,
  5640. ""Third"": 3
  5641. }", json);
  5642. IDictionary<string, int?> v2 = JsonConvert.DeserializeObject<IDictionary<string, int?>>(json);
  5643. Assert.AreEqual(3, v2.Count);
  5644. Assert.AreEqual(1, v2["First"]);
  5645. Assert.AreEqual(null, v2["Second"]);
  5646. Assert.AreEqual(3, v2["Third"]);
  5647. }
  5648. [Test]
  5649. public void UsingJsonTextWriter()
  5650. {
  5651. // The property of the object has to be a number for the cast exception to occure
  5652. object o = new { p = 1 };
  5653. var json = JObject.FromObject(o);
  5654. using (var sw = new StringWriter())
  5655. using (var jw = new JsonTextWriter(sw))
  5656. {
  5657. jw.WriteToken(json.CreateReader());
  5658. jw.Flush();
  5659. string result = sw.ToString();
  5660. Assert.AreEqual(@"{""p"":1}", result);
  5661. }
  5662. }
  5663. #if !(NET35 || NET20 || PORTABLE || PORTABLE40)
  5664. [Test]
  5665. public void DeserializeConcurrentDictionary()
  5666. {
  5667. IDictionary<string, Component> components = new Dictionary<string, Component>
  5668. {
  5669. { "Key!", new Component() }
  5670. };
  5671. GameObject go = new GameObject
  5672. {
  5673. Components = new ConcurrentDictionary<string, Component>(components),
  5674. Id = "Id!",
  5675. Name = "Name!"
  5676. };
  5677. string originalJson = JsonConvert.SerializeObject(go, Formatting.Indented);
  5678. Assert.AreEqual(@"{
  5679. ""Components"": {
  5680. ""Key!"": {}
  5681. },
  5682. ""Id"": ""Id!"",
  5683. ""Name"": ""Name!""
  5684. }", originalJson);
  5685. GameObject newObject = JsonConvert.DeserializeObject<GameObject>(originalJson);
  5686. Assert.AreEqual(1, newObject.Components.Count);
  5687. Assert.AreEqual("Id!", newObject.Id);
  5688. Assert.AreEqual("Name!", newObject.Name);
  5689. }
  5690. #endif
  5691. [Test]
  5692. public void DeserializeKeyValuePairArray()
  5693. {
  5694. string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]";
  5695. IList<KeyValuePair<string, IList<string>>> values = JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>>>(json);
  5696. Assert.AreEqual(2, values.Count);
  5697. Assert.AreEqual("aaa", values[0].Key);
  5698. Assert.AreEqual(2, values[0].Value.Count);
  5699. Assert.AreEqual("1", values[0].Value[0]);
  5700. Assert.AreEqual("2", values[0].Value[1]);
  5701. Assert.AreEqual("bbb", values[1].Key);
  5702. Assert.AreEqual(2, values[1].Value.Count);
  5703. Assert.AreEqual("3", values[1].Value[0]);
  5704. Assert.AreEqual("4", values[1].Value[1]);
  5705. }
  5706. [Test]
  5707. public void DeserializeNullableKeyValuePairArray()
  5708. {
  5709. string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, null, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]";
  5710. IList<KeyValuePair<string, IList<string>>?> values = JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>?>>(json);
  5711. Assert.AreEqual(3, values.Count);
  5712. Assert.AreEqual("aaa", values[0].Value.Key);
  5713. Assert.AreEqual(2, values[0].Value.Value.Count);
  5714. Assert.AreEqual("1", values[0].Value.Value[0]);
  5715. Assert.AreEqual("2", values[0].Value.Value[1]);
  5716. Assert.AreEqual(null, values[1]);
  5717. Assert.AreEqual("bbb", values[2].Value.Key);
  5718. Assert.AreEqual(2, values[2].Value.Value.Count);
  5719. Assert.AreEqual("3", values[2].Value.Value[0]);
  5720. Assert.AreEqual("4", values[2].Value.Value[1]);
  5721. }
  5722. [Test]
  5723. public void DeserializeNullToNonNullableKeyValuePairArray()
  5724. {
  5725. string json = @"[ null ]";
  5726. ExceptionAssert.Throws<JsonSerializationException>(
  5727. "Cannot convert null value to KeyValuePair. Path '[0]', line 1, position 6.",
  5728. () => { JsonConvert.DeserializeObject<IList<KeyValuePair<string, IList<string>>>>(json); });
  5729. }
  5730. [Test]
  5731. public void SerializeUriWithQuotes()
  5732. {
  5733. string input = "http://test.com/%22foo+bar%22";
  5734. Uri uri = new Uri(input);
  5735. string json = JsonConvert.SerializeObject(uri);
  5736. Uri output = JsonConvert.DeserializeObject<Uri>(json);
  5737. Assert.AreEqual(uri, output);
  5738. }
  5739. [Test]
  5740. public void SerializeUriWithSlashes()
  5741. {
  5742. string input = @"http://tes/?a=b\\c&d=e\";
  5743. Uri uri = new Uri(input);
  5744. string json = JsonConvert.SerializeObject(uri);
  5745. Uri output = JsonConvert.DeserializeObject<Uri>(json);
  5746. Assert.AreEqual(uri, output);
  5747. }
  5748. [Test]
  5749. public void DeserializeByteArrayWithTypeNameHandling()
  5750. {
  5751. TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 });
  5752. JsonSerializer serializer = new JsonSerializer();
  5753. serializer.TypeNameHandling = TypeNameHandling.All;
  5754. byte[] objectBytes;
  5755. using (MemoryStream bsonStream = new MemoryStream())
  5756. using (JsonWriter bsonWriter = new JsonTextWriter(new StreamWriter(bsonStream)))
  5757. {
  5758. serializer.Serialize(bsonWriter, test);
  5759. bsonWriter.Flush();
  5760. objectBytes = bsonStream.ToArray();
  5761. }
  5762. using (MemoryStream bsonStream = new MemoryStream(objectBytes))
  5763. using (JsonReader bsonReader = new JsonTextReader(new StreamReader(bsonStream)))
  5764. {
  5765. // Get exception here
  5766. TestObject newObject = (TestObject)serializer.Deserialize(bsonReader);
  5767. Assert.AreEqual("Test", newObject.Name);
  5768. CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data);
  5769. }
  5770. }
  5771. #if !(NET20 || NETFX_CORE)
  5772. [Test]
  5773. public void DeserializeDecimalsWithCulture()
  5774. {
  5775. CultureInfo initialCulture = Thread.CurrentThread.CurrentCulture;
  5776. try
  5777. {
  5778. CultureInfo testCulture = CultureInfo.CreateSpecificCulture("nb-NO");
  5779. Thread.CurrentThread.CurrentCulture = testCulture;
  5780. Thread.CurrentThread.CurrentUICulture = testCulture;
  5781. string json = @"{ 'Quantity': '1.5', 'OptionalQuantity': '2.2' }";
  5782. DecimalTestClass c = JsonConvert.DeserializeObject<DecimalTestClass>(json);
  5783. Assert.AreEqual(1.5m, c.Quantity);
  5784. Assert.AreEqual(2.2d, c.OptionalQuantity);
  5785. }
  5786. finally
  5787. {
  5788. Thread.CurrentThread.CurrentCulture = initialCulture;
  5789. Thread.CurrentThread.CurrentUICulture = initialCulture;
  5790. }
  5791. }
  5792. #endif
  5793. [Test]
  5794. public void ReadForTypeHackFixDecimal()
  5795. {
  5796. IList<decimal> d1 = new List<decimal> { 1.1m };
  5797. string json = JsonConvert.SerializeObject(d1);
  5798. IList<decimal> d2 = JsonConvert.DeserializeObject<IList<decimal>>(json);
  5799. Assert.AreEqual(d1.Count, d2.Count);
  5800. Assert.AreEqual(d1[0], d2[0]);
  5801. }
  5802. [Test]
  5803. public void ReadForTypeHackFixDateTimeOffset()
  5804. {
  5805. IList<DateTimeOffset?> d1 = new List<DateTimeOffset?> { null };
  5806. string json = JsonConvert.SerializeObject(d1);
  5807. IList<DateTimeOffset?> d2 = JsonConvert.DeserializeObject<IList<DateTimeOffset?>>(json);
  5808. Assert.AreEqual(d1.Count, d2.Count);
  5809. Assert.AreEqual(d1[0], d2[0]);
  5810. }
  5811. [Test]
  5812. public void ReadForTypeHackFixByteArray()
  5813. {
  5814. IList<byte[]> d1 = new List<byte[]> { null };
  5815. string json = JsonConvert.SerializeObject(d1);
  5816. IList<byte[]> d2 = JsonConvert.DeserializeObject<IList<byte[]>>(json);
  5817. Assert.AreEqual(d1.Count, d2.Count);
  5818. Assert.AreEqual(d1[0], d2[0]);
  5819. }
  5820. [Test]
  5821. public void SerializeInheritanceHierarchyWithDuplicateProperty()
  5822. {
  5823. Bb b = new Bb();
  5824. b.no = true;
  5825. Aa a = b;
  5826. a.no = int.MaxValue;
  5827. string json = JsonConvert.SerializeObject(b);
  5828. Assert.AreEqual(@"{""no"":true}", json);
  5829. Bb b2 = JsonConvert.DeserializeObject<Bb>(json);
  5830. Assert.AreEqual(true, b2.no);
  5831. }
  5832. [Test]
  5833. public void DeserializeNullInt()
  5834. {
  5835. string json = @"[
  5836. 1,
  5837. 2,
  5838. 3,
  5839. null
  5840. ]";
  5841. ExceptionAssert.Throws<JsonSerializationException>(
  5842. "Error converting value {null} to type 'System.Int32'. Path '[3]', line 5, position 7.",
  5843. () => { List<int> numbers = JsonConvert.DeserializeObject<List<int>>(json); });
  5844. }
  5845. #if !(PORTABLE || NETFX_CORE)
  5846. public class ConvertableIntTestClass
  5847. {
  5848. public ConvertibleInt Integer { get; set; }
  5849. public ConvertibleInt? NullableInteger1 { get; set; }
  5850. public ConvertibleInt? NullableInteger2 { get; set; }
  5851. }
  5852. [Test]
  5853. public void SerializeIConvertible()
  5854. {
  5855. ConvertableIntTestClass c = new ConvertableIntTestClass
  5856. {
  5857. Integer = new ConvertibleInt(1),
  5858. NullableInteger1 = new ConvertibleInt(2),
  5859. NullableInteger2 = null
  5860. };
  5861. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  5862. Assert.AreEqual(@"{
  5863. ""Integer"": 1,
  5864. ""NullableInteger1"": 2,
  5865. ""NullableInteger2"": null
  5866. }", json);
  5867. }
  5868. [Test]
  5869. public void DeserializeIConvertible()
  5870. {
  5871. string json = @"{
  5872. ""Integer"": 1,
  5873. ""NullableInteger1"": 2,
  5874. ""NullableInteger2"": null
  5875. }";
  5876. ExceptionAssert.Throws<JsonSerializationException>(
  5877. "Error converting value 1 to type 'Newtonsoft.Json.Tests.ConvertibleInt'. Path 'Integer', line 2, position 15.",
  5878. () => JsonConvert.DeserializeObject<ConvertableIntTestClass>(json));
  5879. }
  5880. #endif
  5881. [Test]
  5882. public void SerializeNullableWidgetStruct()
  5883. {
  5884. Widget widget = new Widget { Id = new WidgetId { Value = "id" } };
  5885. string json = JsonConvert.SerializeObject(widget);
  5886. Assert.AreEqual(@"{""Id"":{""Value"":""id""}}", json);
  5887. }
  5888. [Test]
  5889. public void DeserializeNullableWidgetStruct()
  5890. {
  5891. string json = @"{""Id"":{""Value"":""id""}}";
  5892. Widget w = JsonConvert.DeserializeObject<Widget>(json);
  5893. Assert.AreEqual(new WidgetId { Value = "id" }, w.Id);
  5894. Assert.AreEqual(new WidgetId { Value = "id" }, w.Id.Value);
  5895. Assert.AreEqual("id", w.Id.Value.Value);
  5896. }
  5897. [Test]
  5898. public void DeserializeBoolInt()
  5899. {
  5900. ExceptionAssert.Throws<JsonReaderException>(
  5901. "Error reading integer. Unexpected token: Boolean. Path 'PreProperty', line 2, position 22.",
  5902. () =>
  5903. {
  5904. string json = @"{
  5905. ""PreProperty"": true,
  5906. ""PostProperty"": ""-1""
  5907. }";
  5908. JsonConvert.DeserializeObject<TestObjects.MyClass>(json);
  5909. });
  5910. }
  5911. [Test]
  5912. public void DeserializeUnexpectedEndInt()
  5913. {
  5914. ExceptionAssert.Throws<JsonException>(
  5915. null,
  5916. () =>
  5917. {
  5918. string json = @"{
  5919. ""PreProperty"": ";
  5920. JsonConvert.DeserializeObject<TestObjects.MyClass>(json);
  5921. });
  5922. }
  5923. [Test]
  5924. public void DeserializeNullableGuid()
  5925. {
  5926. string json = @"{""Id"":null}";
  5927. var c = JsonConvert.DeserializeObject<NullableGuid>(json);
  5928. Assert.AreEqual(null, c.Id);
  5929. json = @"{""Id"":""d8220a4b-75b1-4b7a-8112-b7bdae956a45""}";
  5930. c = JsonConvert.DeserializeObject<NullableGuid>(json);
  5931. Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), c.Id);
  5932. }
  5933. [Test]
  5934. public void DeserializeGuid()
  5935. {
  5936. Item expected = new Item()
  5937. {
  5938. SourceTypeID = new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"),
  5939. BrokerID = new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"),
  5940. Latitude = 33.657145,
  5941. Longitude = -117.766684,
  5942. TimeStamp = new DateTime(2000, 3, 1, 23, 59, 59, DateTimeKind.Utc),
  5943. Payload = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
  5944. };
  5945. string jsonString = JsonConvert.SerializeObject(expected, Formatting.Indented);
  5946. Assert.AreEqual(@"{
  5947. ""SourceTypeID"": ""d8220a4b-75b1-4b7a-8112-b7bdae956a45"",
  5948. ""BrokerID"": ""951663c4-924e-4c86-a57a-7ed737501dbd"",
  5949. ""Latitude"": 33.657145,
  5950. ""Longitude"": -117.766684,
  5951. ""TimeStamp"": ""2000-03-01T23:59:59Z"",
  5952. ""Payload"": {
  5953. ""$type"": ""System.Byte[], mscorlib"",
  5954. ""$value"": ""AAECAwQFBgcICQ==""
  5955. }
  5956. }", jsonString);
  5957. Item actual = JsonConvert.DeserializeObject<Item>(jsonString);
  5958. Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), actual.SourceTypeID);
  5959. Assert.AreEqual(new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"), actual.BrokerID);
  5960. byte[] bytes = (byte[])actual.Payload;
  5961. CollectionAssert.AreEquivalent((new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }).ToList(), bytes.ToList());
  5962. }
  5963. [Test]
  5964. public void DeserializeObjectDictionary()
  5965. {
  5966. var serializer = JsonSerializer.Create(new JsonSerializerSettings());
  5967. var dict = serializer.Deserialize<Dictionary<string, string>>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}")));
  5968. Assert.AreEqual("", dict["k1"]);
  5969. Assert.AreEqual("v2", dict["k2"]);
  5970. }
  5971. [Test]
  5972. public void DeserializeNullableEnum()
  5973. {
  5974. string json = JsonConvert.SerializeObject(new WithEnums
  5975. {
  5976. Id = 7,
  5977. NullableEnum = null
  5978. });
  5979. Assert.AreEqual(@"{""Id"":7,""NullableEnum"":null}", json);
  5980. WithEnums e = JsonConvert.DeserializeObject<WithEnums>(json);
  5981. Assert.AreEqual(null, e.NullableEnum);
  5982. json = JsonConvert.SerializeObject(new WithEnums
  5983. {
  5984. Id = 7,
  5985. NullableEnum = MyEnum.Value2
  5986. });
  5987. Assert.AreEqual(@"{""Id"":7,""NullableEnum"":1}", json);
  5988. e = JsonConvert.DeserializeObject<WithEnums>(json);
  5989. Assert.AreEqual(MyEnum.Value2, e.NullableEnum);
  5990. }
  5991. [Test]
  5992. public void NullableStructWithConverter()
  5993. {
  5994. string json = JsonConvert.SerializeObject(new Widget1 { Id = new WidgetId1 { Value = 1234 } });
  5995. Assert.AreEqual(@"{""Id"":""1234""}", json);
  5996. Widget1 w = JsonConvert.DeserializeObject<Widget1>(@"{""Id"":""1234""}");
  5997. Assert.AreEqual(new WidgetId1 { Value = 1234 }, w.Id);
  5998. }
  5999. [Test]
  6000. public void SerializeDictionaryStringStringAndStringObject()
  6001. {
  6002. var serializer = JsonSerializer.Create(new JsonSerializerSettings());
  6003. var dict = serializer.Deserialize<Dictionary<string, string>>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}")));
  6004. var reader = new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}"));
  6005. var dict2 = serializer.Deserialize<Dictionary<string, object>>(reader);
  6006. Assert.AreEqual(dict["k1"], dict2["k1"]);
  6007. }
  6008. [Test]
  6009. public void DeserializeEmptyStrings()
  6010. {
  6011. object v = JsonConvert.DeserializeObject<double?>("");
  6012. Assert.IsNull(v);
  6013. v = JsonConvert.DeserializeObject<char?>("");
  6014. Assert.IsNull(v);
  6015. v = JsonConvert.DeserializeObject<int?>("");
  6016. Assert.IsNull(v);
  6017. v = JsonConvert.DeserializeObject<decimal?>("");
  6018. Assert.IsNull(v);
  6019. v = JsonConvert.DeserializeObject<DateTime?>("");
  6020. Assert.IsNull(v);
  6021. v = JsonConvert.DeserializeObject<DateTimeOffset?>("");
  6022. Assert.IsNull(v);
  6023. v = JsonConvert.DeserializeObject<byte[]>("");
  6024. Assert.IsNull(v);
  6025. }
  6026. public class Sdfsdf
  6027. {
  6028. public double Id { get; set; }
  6029. }
  6030. [Test]
  6031. public void DeserializeDoubleFromEmptyString()
  6032. {
  6033. ExceptionAssert.Throws<JsonSerializationException>(
  6034. "No JSON content found and type 'System.Double' is not nullable. Path '', line 0, position 0.",
  6035. () => { JsonConvert.DeserializeObject<double>(""); });
  6036. }
  6037. [Test]
  6038. public void DeserializeEnumFromEmptyString()
  6039. {
  6040. ExceptionAssert.Throws<JsonSerializationException>(
  6041. "No JSON content found and type 'System.StringComparison' is not nullable. Path '', line 0, position 0.",
  6042. () => { JsonConvert.DeserializeObject<StringComparison>(""); });
  6043. }
  6044. [Test]
  6045. public void DeserializeInt32FromEmptyString()
  6046. {
  6047. ExceptionAssert.Throws<JsonSerializationException>(
  6048. "No JSON content found and type 'System.Int32' is not nullable. Path '', line 0, position 0.",
  6049. () => { JsonConvert.DeserializeObject<int>(""); });
  6050. }
  6051. [Test]
  6052. public void DeserializeByteArrayFromEmptyString()
  6053. {
  6054. byte[] b = JsonConvert.DeserializeObject<byte[]>("");
  6055. Assert.IsNull(b);
  6056. }
  6057. [Test]
  6058. public void DeserializeDoubleFromNullString()
  6059. {
  6060. ExceptionAssert.Throws<ArgumentNullException>(
  6061. @"Value cannot be null.
  6062. Parameter name: value",
  6063. () => { JsonConvert.DeserializeObject<double>(null); });
  6064. }
  6065. [Test]
  6066. public void DeserializeFromNullString()
  6067. {
  6068. ExceptionAssert.Throws<ArgumentNullException>(
  6069. @"Value cannot be null.
  6070. Parameter name: value",
  6071. () => { JsonConvert.DeserializeObject(null); });
  6072. }
  6073. [Test]
  6074. public void DeserializeIsoDatesWithIsoConverter()
  6075. {
  6076. string jsonIsoText =
  6077. @"{""Value"":""2012-02-25T19:55:50.6095676+13:00""}";
  6078. DateTimeWrapper c = JsonConvert.DeserializeObject<DateTimeWrapper>(jsonIsoText, new IsoDateTimeConverter());
  6079. Assert.AreEqual(DateTimeKind.Local, c.Value.Kind);
  6080. }
  6081. #if !NET20
  6082. [Test]
  6083. public void DeserializeUTC()
  6084. {
  6085. DateTimeTestClass c =
  6086. JsonConvert.DeserializeObject<DateTimeTestClass>(
  6087. @"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}",
  6088. new JsonSerializerSettings
  6089. {
  6090. DateTimeZoneHandling = DateTimeZoneHandling.Local
  6091. });
  6092. Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField);
  6093. Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField);
  6094. Assert.AreEqual("Pre", c.PreField);
  6095. Assert.AreEqual("Post", c.PostField);
  6096. DateTimeTestClass c2 =
  6097. JsonConvert.DeserializeObject<DateTimeTestClass>(
  6098. @"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""DateTimeOffsetField"":""2008-01-01T01:01:01Z"",""PostField"":""Post""}",
  6099. new JsonSerializerSettings
  6100. {
  6101. DateTimeZoneHandling = DateTimeZoneHandling.Local
  6102. });
  6103. Assert.AreEqual(new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(), c2.DateTimeField);
  6104. Assert.AreEqual(new DateTimeOffset(2008, 1, 1, 1, 1, 1, 0, TimeSpan.Zero), c2.DateTimeOffsetField);
  6105. Assert.AreEqual("Pre", c2.PreField);
  6106. Assert.AreEqual("Post", c2.PostField);
  6107. }
  6108. [Test]
  6109. public void NullableDeserializeUTC()
  6110. {
  6111. NullableDateTimeTestClass c =
  6112. JsonConvert.DeserializeObject<NullableDateTimeTestClass>(
  6113. @"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}",
  6114. new JsonSerializerSettings
  6115. {
  6116. DateTimeZoneHandling = DateTimeZoneHandling.Local
  6117. });
  6118. Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField);
  6119. Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField);
  6120. Assert.AreEqual("Pre", c.PreField);
  6121. Assert.AreEqual("Post", c.PostField);
  6122. NullableDateTimeTestClass c2 =
  6123. JsonConvert.DeserializeObject<NullableDateTimeTestClass>(
  6124. @"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}");
  6125. Assert.AreEqual(null, c2.DateTimeField);
  6126. Assert.AreEqual(null, c2.DateTimeOffsetField);
  6127. Assert.AreEqual("Pre", c2.PreField);
  6128. Assert.AreEqual("Post", c2.PostField);
  6129. }
  6130. [Test]
  6131. public void PrivateConstructor()
  6132. {
  6133. var person = PersonWithPrivateConstructor.CreatePerson();
  6134. person.Name = "John Doe";
  6135. person.Age = 25;
  6136. var serializedPerson = JsonConvert.SerializeObject(person);
  6137. var roundtrippedPerson = JsonConvert.DeserializeObject<PersonWithPrivateConstructor>(serializedPerson);
  6138. Assert.AreEqual(person.Name, roundtrippedPerson.Name);
  6139. }
  6140. #endif
  6141. #if !(NETFX_CORE)
  6142. [Test]
  6143. public void MetroBlogPost()
  6144. {
  6145. Product product = new Product();
  6146. product.Name = "Apple";
  6147. product.ExpiryDate = new DateTime(2012, 4, 1);
  6148. product.Price = 3.99M;
  6149. product.Sizes = new[] { "Small", "Medium", "Large" };
  6150. string json = JsonConvert.SerializeObject(product);
  6151. //{
  6152. // "Name": "Apple",
  6153. // "ExpiryDate": "2012-04-01T00:00:00",
  6154. // "Price": 3.99,
  6155. // "Sizes": [ "Small", "Medium", "Large" ]
  6156. //}
  6157. string metroJson = JsonConvert.SerializeObject(product, new JsonSerializerSettings
  6158. {
  6159. ContractResolver = new MetroPropertyNameResolver(),
  6160. Converters = { new MetroStringConverter() },
  6161. Formatting = Formatting.Indented
  6162. });
  6163. Assert.AreEqual(@"{
  6164. "":::NAME:::"": "":::APPLE:::"",
  6165. "":::EXPIRYDATE:::"": ""2012-04-01T00:00:00"",
  6166. "":::PRICE:::"": 3.99,
  6167. "":::SIZES:::"": [
  6168. "":::SMALL:::"",
  6169. "":::MEDIUM:::"",
  6170. "":::LARGE:::""
  6171. ]
  6172. }", metroJson);
  6173. //{
  6174. // ":::NAME:::": ":::APPLE:::",
  6175. // ":::EXPIRYDATE:::": "2012-04-01T00:00:00",
  6176. // ":::PRICE:::": 3.99,
  6177. // ":::SIZES:::": [ ":::SMALL:::", ":::MEDIUM:::", ":::LARGE:::" ]
  6178. //}
  6179. Color[] colors = new[] { Color.Blue, Color.Red, Color.Yellow, Color.Green, Color.Black, Color.Brown };
  6180. string json2 = JsonConvert.SerializeObject(colors, new JsonSerializerSettings
  6181. {
  6182. ContractResolver = new MetroPropertyNameResolver(),
  6183. Converters = { new MetroStringConverter(), new MetroColorConverter() },
  6184. Formatting = Formatting.Indented
  6185. });
  6186. Assert.AreEqual(@"[
  6187. "":::GRAY:::"",
  6188. "":::GRAY:::"",
  6189. "":::GRAY:::"",
  6190. "":::GRAY:::"",
  6191. "":::BLACK:::"",
  6192. "":::GRAY:::""
  6193. ]", json2);
  6194. }
  6195. public class MetroColorConverter : JsonConverter
  6196. {
  6197. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  6198. {
  6199. Color color = (Color)value;
  6200. Color fixedColor = (color == Color.White || color == Color.Black) ? color : Color.Gray;
  6201. writer.WriteValue(":::" + fixedColor.ToKnownColor().ToString().ToUpper() + ":::");
  6202. }
  6203. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  6204. {
  6205. return Enum.Parse(typeof(Color), reader.Value.ToString());
  6206. }
  6207. public override bool CanConvert(Type objectType)
  6208. {
  6209. return objectType == typeof(Color);
  6210. }
  6211. }
  6212. #endif
  6213. public class MultipleItemsClass
  6214. {
  6215. public string Name { get; set; }
  6216. }
  6217. [Test]
  6218. public void MultipleItems()
  6219. {
  6220. IList<MultipleItemsClass> values = new List<MultipleItemsClass>();
  6221. JsonTextReader reader = new JsonTextReader(new StringReader(@"{ ""name"": ""bar"" }{ ""name"": ""baz"" }"));
  6222. reader.SupportMultipleContent = true;
  6223. while (true)
  6224. {
  6225. if (!reader.Read())
  6226. break;
  6227. JsonSerializer serializer = new JsonSerializer();
  6228. MultipleItemsClass foo = serializer.Deserialize<MultipleItemsClass>(reader);
  6229. values.Add(foo);
  6230. }
  6231. Assert.AreEqual(2, values.Count);
  6232. Assert.AreEqual("bar", values[0].Name);
  6233. Assert.AreEqual("baz", values[1].Name);
  6234. }
  6235. private class FooBar
  6236. {
  6237. public DateTimeOffset Foo { get; set; }
  6238. }
  6239. [Test]
  6240. public void TokenFromBson()
  6241. {
  6242. MemoryStream ms = new MemoryStream();
  6243. BsonWriter writer = new BsonWriter(ms);
  6244. writer.WriteStartArray();
  6245. writer.WriteValue("2000-01-02T03:04:05+06:00");
  6246. writer.WriteEndArray();
  6247. byte[] data = ms.ToArray();
  6248. BsonReader reader = new BsonReader(new MemoryStream(data))
  6249. {
  6250. ReadRootValueAsArray = true
  6251. };
  6252. JArray a = (JArray)JArray.ReadFrom(reader);
  6253. JValue v = (JValue)a[0];
  6254. Console.WriteLine(v.Value.GetType());
  6255. Console.WriteLine(a.ToString());
  6256. }
  6257. [Test]
  6258. public void ObjectRequiredDeserializeMissing()
  6259. {
  6260. string json = "{}";
  6261. IList<string> errors = new List<string>();
  6262. EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> error = (s, e) =>
  6263. {
  6264. errors.Add(e.ErrorContext.Error.Message);
  6265. e.ErrorContext.Handled = true;
  6266. };
  6267. var o = JsonConvert.DeserializeObject<RequiredObject>(json, new JsonSerializerSettings
  6268. {
  6269. Error = error
  6270. });
  6271. Assert.IsNotNull(o);
  6272. Assert.AreEqual(4, errors.Count);
  6273. Assert.IsTrue(errors[0].StartsWith("Required property 'NonAttributeProperty' not found in JSON. Path ''"));
  6274. Assert.IsTrue(errors[1].StartsWith("Required property 'UnsetProperty' not found in JSON. Path ''"));
  6275. Assert.IsTrue(errors[2].StartsWith("Required property 'AllowNullProperty' not found in JSON. Path ''"));
  6276. Assert.IsTrue(errors[3].StartsWith("Required property 'AlwaysProperty' not found in JSON. Path ''"));
  6277. }
  6278. [Test]
  6279. public void ObjectRequiredDeserializeNull()
  6280. {
  6281. string json = "{'NonAttributeProperty':null,'UnsetProperty':null,'AllowNullProperty':null,'AlwaysProperty':null}";
  6282. IList<string> errors = new List<string>();
  6283. EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> error = (s, e) =>
  6284. {
  6285. errors.Add(e.ErrorContext.Error.Message);
  6286. e.ErrorContext.Handled = true;
  6287. };
  6288. var o = JsonConvert.DeserializeObject<RequiredObject>(json, new JsonSerializerSettings
  6289. {
  6290. Error = error
  6291. });
  6292. Assert.IsNotNull(o);
  6293. Assert.AreEqual(3, errors.Count);
  6294. Assert.IsTrue(errors[0].StartsWith("Required property 'NonAttributeProperty' expects a value but got null. Path ''"));
  6295. Assert.IsTrue(errors[1].StartsWith("Required property 'UnsetProperty' expects a value but got null. Path ''"));
  6296. Assert.IsTrue(errors[2].StartsWith("Required property 'AlwaysProperty' expects a value but got null. Path ''"));
  6297. }
  6298. [Test]
  6299. public void ObjectRequiredSerialize()
  6300. {
  6301. IList<string> errors = new List<string>();
  6302. EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> error = (s, e) =>
  6303. {
  6304. errors.Add(e.ErrorContext.Error.Message);
  6305. e.ErrorContext.Handled = true;
  6306. };
  6307. string json = JsonConvert.SerializeObject(new RequiredObject(), new JsonSerializerSettings
  6308. {
  6309. Error = error,
  6310. Formatting = Formatting.Indented
  6311. });
  6312. Assert.AreEqual(@"{
  6313. ""DefaultProperty"": null,
  6314. ""AllowNullProperty"": null
  6315. }", json);
  6316. Assert.AreEqual(3, errors.Count);
  6317. Assert.AreEqual("Cannot write a null value for property 'NonAttributeProperty'. Property requires a value. Path ''.", errors[0]);
  6318. Assert.AreEqual("Cannot write a null value for property 'UnsetProperty'. Property requires a value. Path ''.", errors[1]);
  6319. Assert.AreEqual("Cannot write a null value for property 'AlwaysProperty'. Property requires a value. Path ''.", errors[2]);
  6320. }
  6321. [Test]
  6322. public void DeserializeCollectionItemConverter()
  6323. {
  6324. PropertyItemConverter c = new PropertyItemConverter
  6325. {
  6326. Data =
  6327. new[]
  6328. {
  6329. "one",
  6330. "two",
  6331. "three"
  6332. }
  6333. };
  6334. var c2 = JsonConvert.DeserializeObject<PropertyItemConverter>("{'Data':['::ONE::','::TWO::']}");
  6335. Assert.IsNotNull(c2);
  6336. Assert.AreEqual(2, c2.Data.Count);
  6337. Assert.AreEqual("one", c2.Data[0]);
  6338. Assert.AreEqual("two", c2.Data[1]);
  6339. }
  6340. [Test]
  6341. public void SerializeCollectionItemConverter()
  6342. {
  6343. PropertyItemConverter c = new PropertyItemConverter
  6344. {
  6345. Data = new[]
  6346. {
  6347. "one",
  6348. "two",
  6349. "three"
  6350. }
  6351. };
  6352. string json = JsonConvert.SerializeObject(c);
  6353. Assert.AreEqual(@"{""Data"":["":::ONE:::"","":::TWO:::"","":::THREE:::""]}", json);
  6354. }
  6355. #if !NET20
  6356. [Test]
  6357. public void DateTimeDictionaryKey_DateTimeOffset_Iso()
  6358. {
  6359. IDictionary<DateTimeOffset, int> dic1 = new Dictionary<DateTimeOffset, int>
  6360. {
  6361. { new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1 },
  6362. { new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2 }
  6363. };
  6364. string json = JsonConvert.SerializeObject(dic1, Formatting.Indented);
  6365. Assert.AreEqual(@"{
  6366. ""2000-12-12T12:12:12+00:00"": 1,
  6367. ""2013-12-12T12:12:12+00:00"": 2
  6368. }", json);
  6369. IDictionary<DateTimeOffset, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTimeOffset, int>>(json);
  6370. Assert.AreEqual(2, dic2.Count);
  6371. Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
  6372. Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
  6373. }
  6374. [Test]
  6375. public void DateTimeDictionaryKey_DateTimeOffset_MS()
  6376. {
  6377. IDictionary<DateTimeOffset?, int> dic1 = new Dictionary<DateTimeOffset?, int>
  6378. {
  6379. { new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1 },
  6380. { new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2 }
  6381. };
  6382. string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings
  6383. {
  6384. DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
  6385. });
  6386. Assert.AreEqual(@"{
  6387. ""\/Date(976623132000+0000)\/"": 1,
  6388. ""\/Date(1386850332000+0000)\/"": 2
  6389. }", json);
  6390. IDictionary<DateTimeOffset?, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTimeOffset?, int>>(json);
  6391. Assert.AreEqual(2, dic2.Count);
  6392. Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
  6393. Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]);
  6394. }
  6395. #endif
  6396. [Test]
  6397. public void DateTimeDictionaryKey_DateTime_Iso()
  6398. {
  6399. IDictionary<DateTime, int> dic1 = new Dictionary<DateTime, int>
  6400. {
  6401. { new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1 },
  6402. { new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2 }
  6403. };
  6404. string json = JsonConvert.SerializeObject(dic1, Formatting.Indented);
  6405. Assert.AreEqual(@"{
  6406. ""2000-12-12T12:12:12Z"": 1,
  6407. ""2013-12-12T12:12:12Z"": 2
  6408. }", json);
  6409. IDictionary<DateTime, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTime, int>>(json);
  6410. Assert.AreEqual(2, dic2.Count);
  6411. Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
  6412. Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
  6413. }
  6414. [Test]
  6415. public void DateTimeDictionaryKey_DateTime_MS()
  6416. {
  6417. IDictionary<DateTime, int> dic1 = new Dictionary<DateTime, int>
  6418. {
  6419. { new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1 },
  6420. { new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2 }
  6421. };
  6422. string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings
  6423. {
  6424. DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
  6425. });
  6426. Assert.AreEqual(@"{
  6427. ""\/Date(976623132000)\/"": 1,
  6428. ""\/Date(1386850332000)\/"": 2
  6429. }", json);
  6430. IDictionary<DateTime, int> dic2 = JsonConvert.DeserializeObject<IDictionary<DateTime, int>>(json);
  6431. Assert.AreEqual(2, dic2.Count);
  6432. Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
  6433. Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]);
  6434. }
  6435. [Test]
  6436. public void DeserializeEmptyJsonString()
  6437. {
  6438. string s = (string)new JsonSerializer().Deserialize(new JsonTextReader(new StringReader("''")));
  6439. Assert.AreEqual("", s);
  6440. }
  6441. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  6442. [Test]
  6443. public void SerializeAndDeserializeWithAttributes()
  6444. {
  6445. var testObj = new PersonSerializable() { Name = "John Doe", Age = 28 };
  6446. var objDeserialized = SerializeAndDeserialize<PersonSerializable>(testObj);
  6447. Assert.AreEqual(testObj.Name, objDeserialized.Name);
  6448. Assert.AreEqual(0, objDeserialized.Age);
  6449. }
  6450. private T SerializeAndDeserialize<T>(T obj)
  6451. where T : class
  6452. {
  6453. var json = Serialize(obj);
  6454. return Deserialize<T>(json);
  6455. }
  6456. private string Serialize<T>(T obj)
  6457. where T : class
  6458. {
  6459. var stringWriter = new StringWriter();
  6460. var serializer = new Newtonsoft.Json.JsonSerializer();
  6461. serializer.ContractResolver = new DefaultContractResolver(false)
  6462. {
  6463. IgnoreSerializableAttribute = false
  6464. };
  6465. serializer.Serialize(stringWriter, obj);
  6466. return stringWriter.ToString();
  6467. }
  6468. private T Deserialize<T>(string json)
  6469. where T : class
  6470. {
  6471. var jsonReader = new Newtonsoft.Json.JsonTextReader(new StringReader(json));
  6472. var serializer = new Newtonsoft.Json.JsonSerializer();
  6473. serializer.ContractResolver = new DefaultContractResolver(false)
  6474. {
  6475. IgnoreSerializableAttribute = false
  6476. };
  6477. return serializer.Deserialize(jsonReader, typeof(T)) as T;
  6478. }
  6479. #endif
  6480. [Test]
  6481. public void PropertyItemConverter()
  6482. {
  6483. Event e = new Event
  6484. {
  6485. EventName = "Blackadder III",
  6486. Venue = "Gryphon Theatre",
  6487. Performances = new List<DateTime>
  6488. {
  6489. DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336458600000),
  6490. DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336545000000),
  6491. DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336636800000)
  6492. }
  6493. };
  6494. string json = JsonConvert.SerializeObject(e, Formatting.Indented);
  6495. //{
  6496. // "EventName": "Blackadder III",
  6497. // "Venue": "Gryphon Theatre",
  6498. // "Performances": [
  6499. // new Date(1336458600000),
  6500. // new Date(1336545000000),
  6501. // new Date(1336636800000)
  6502. // ]
  6503. //}
  6504. Assert.AreEqual(@"{
  6505. ""EventName"": ""Blackadder III"",
  6506. ""Venue"": ""Gryphon Theatre"",
  6507. ""Performances"": [
  6508. new Date(
  6509. 1336458600000
  6510. ),
  6511. new Date(
  6512. 1336545000000
  6513. ),
  6514. new Date(
  6515. 1336636800000
  6516. )
  6517. ]
  6518. }", json);
  6519. }
  6520. #if !(NET20 || NET35)
  6521. public class IgnoreDataMemberTestClass
  6522. {
  6523. [IgnoreDataMember]
  6524. public int Ignored { get; set; }
  6525. }
  6526. [Test]
  6527. public void IgnoreDataMemberTest()
  6528. {
  6529. string json = JsonConvert.SerializeObject(new IgnoreDataMemberTestClass() { Ignored = int.MaxValue }, Formatting.Indented);
  6530. Assert.AreEqual(@"{}", json);
  6531. }
  6532. #endif
  6533. #if !(NET20 || NET35)
  6534. [Test]
  6535. public void SerializeDataContractSerializationAttributes()
  6536. {
  6537. DataContractSerializationAttributesClass dataContract = new DataContractSerializationAttributesClass
  6538. {
  6539. NoAttribute = "Value!",
  6540. IgnoreDataMemberAttribute = "Value!",
  6541. DataMemberAttribute = "Value!",
  6542. IgnoreDataMemberAndDataMemberAttribute = "Value!"
  6543. };
  6544. //MemoryStream ms = new MemoryStream();
  6545. //DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DataContractSerializationAttributesClass));
  6546. //serializer.WriteObject(ms, dataContract);
  6547. //Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
  6548. string json = JsonConvert.SerializeObject(dataContract, Formatting.Indented);
  6549. Assert.AreEqual(@"{
  6550. ""DataMemberAttribute"": ""Value!"",
  6551. ""IgnoreDataMemberAndDataMemberAttribute"": ""Value!""
  6552. }", json);
  6553. PocoDataContractSerializationAttributesClass poco = new PocoDataContractSerializationAttributesClass
  6554. {
  6555. NoAttribute = "Value!",
  6556. IgnoreDataMemberAttribute = "Value!",
  6557. DataMemberAttribute = "Value!",
  6558. IgnoreDataMemberAndDataMemberAttribute = "Value!"
  6559. };
  6560. json = JsonConvert.SerializeObject(poco, Formatting.Indented);
  6561. Assert.AreEqual(@"{
  6562. ""NoAttribute"": ""Value!"",
  6563. ""DataMemberAttribute"": ""Value!""
  6564. }", json);
  6565. }
  6566. #endif
  6567. [Test]
  6568. public void CheckAdditionalContent()
  6569. {
  6570. string json = "{one:1}{}";
  6571. JsonSerializerSettings settings = new JsonSerializerSettings();
  6572. JsonSerializer s = JsonSerializer.Create(settings);
  6573. IDictionary<string, int> o = s.Deserialize<Dictionary<string, int>>(new JsonTextReader(new StringReader(json)));
  6574. Assert.IsNotNull(o);
  6575. Assert.AreEqual(1, o["one"]);
  6576. settings.CheckAdditionalContent = true;
  6577. s = JsonSerializer.Create(settings);
  6578. ExceptionAssert.Throws<JsonReaderException>(
  6579. "Additional text encountered after finished reading JSON content: {. Path '', line 1, position 7.",
  6580. () => { s.Deserialize<Dictionary<string, int>>(new JsonTextReader(new StringReader(json))); });
  6581. }
  6582. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  6583. [Test]
  6584. public void DeserializeException()
  6585. {
  6586. string json = @"{ ""ClassName"" : ""System.InvalidOperationException"",
  6587. ""Data"" : null,
  6588. ""ExceptionMethod"" : ""8\nLogin\nAppBiz, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null\nMyApp.LoginBiz\nMyApp.User Login()"",
  6589. ""HResult"" : -2146233079,
  6590. ""HelpURL"" : null,
  6591. ""InnerException"" : { ""ClassName"" : ""System.Exception"",
  6592. ""Data"" : null,
  6593. ""ExceptionMethod"" : null,
  6594. ""HResult"" : -2146233088,
  6595. ""HelpURL"" : null,
  6596. ""InnerException"" : null,
  6597. ""Message"" : ""Inner exception..."",
  6598. ""RemoteStackIndex"" : 0,
  6599. ""RemoteStackTraceString"" : null,
  6600. ""Source"" : null,
  6601. ""StackTraceString"" : null,
  6602. ""WatsonBuckets"" : null
  6603. },
  6604. ""Message"" : ""Outter exception..."",
  6605. ""RemoteStackIndex"" : 0,
  6606. ""RemoteStackTraceString"" : null,
  6607. ""Source"" : ""AppBiz"",
  6608. ""StackTraceString"" : "" at MyApp.LoginBiz.Login() in C:\\MyApp\\LoginBiz.cs:line 44\r\n at MyApp.LoginSvc.Login() in C:\\MyApp\\LoginSvc.cs:line 71\r\n at SyncInvokeLogin(Object , Object[] , Object[] )\r\n at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)\r\n at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)\r\n at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)"",
  6609. ""WatsonBuckets"" : null
  6610. }";
  6611. InvalidOperationException exception = JsonConvert.DeserializeObject<InvalidOperationException>(json);
  6612. Assert.IsNotNull(exception);
  6613. CustomAssert.IsInstanceOfType(typeof(InvalidOperationException), exception);
  6614. Assert.AreEqual("Outter exception...", exception.Message);
  6615. }
  6616. #endif
  6617. [Test]
  6618. public void AdditionalContentAfterFinish()
  6619. {
  6620. ExceptionAssert.Throws<JsonException>(
  6621. "Additional text found in JSON string after finishing deserializing object.",
  6622. () =>
  6623. {
  6624. string json = "[{},1]";
  6625. JsonSerializer serializer = new JsonSerializer();
  6626. serializer.CheckAdditionalContent = true;
  6627. var reader = new JsonTextReader(new StringReader(json));
  6628. reader.Read();
  6629. reader.Read();
  6630. serializer.Deserialize(reader, typeof(MyType));
  6631. });
  6632. }
  6633. [Test]
  6634. public void DeserializeRelativeUri()
  6635. {
  6636. IList<Uri> uris = JsonConvert.DeserializeObject<IList<Uri>>(@"[""http://localhost/path?query#hash""]");
  6637. Assert.AreEqual(1, uris.Count);
  6638. Assert.AreEqual(new Uri("http://localhost/path?query#hash"), uris[0]);
  6639. Uri uri = JsonConvert.DeserializeObject<Uri>(@"""http://localhost/path?query#hash""");
  6640. Assert.IsNotNull(uri);
  6641. Uri i1 = new Uri("http://localhost/path?query#hash", UriKind.RelativeOrAbsolute);
  6642. Uri i2 = new Uri("http://localhost/path?query#hash");
  6643. Assert.AreEqual(i1, i2);
  6644. uri = JsonConvert.DeserializeObject<Uri>(@"""/path?query#hash""");
  6645. Assert.IsNotNull(uri);
  6646. Assert.AreEqual(new Uri("/path?query#hash", UriKind.RelativeOrAbsolute), uri);
  6647. }
  6648. public class MyConverter : JsonConverter
  6649. {
  6650. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  6651. {
  6652. writer.WriteValue("X");
  6653. }
  6654. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  6655. {
  6656. return "X";
  6657. }
  6658. public override bool CanConvert(Type objectType)
  6659. {
  6660. return true;
  6661. }
  6662. }
  6663. public class MyType
  6664. {
  6665. [JsonProperty(ItemConverterType = typeof(MyConverter))]
  6666. public Dictionary<string, object> MyProperty { get; set; }
  6667. }
  6668. [Test]
  6669. public void DeserializeDictionaryItemConverter()
  6670. {
  6671. var actual = JsonConvert.DeserializeObject<MyType>(@"{ ""MyProperty"":{""Key"":""Y""}}");
  6672. Assert.AreEqual("X", actual.MyProperty["Key"]);
  6673. }
  6674. [Test]
  6675. public void DeserializeCaseInsensitiveKeyValuePairConverter()
  6676. {
  6677. KeyValuePair<int, string> result =
  6678. JsonConvert.DeserializeObject<KeyValuePair<int, string>>(
  6679. "{key: 123, \"VALUE\": \"test value\"}"
  6680. );
  6681. Assert.AreEqual(123, result.Key);
  6682. Assert.AreEqual("test value", result.Value);
  6683. }
  6684. [Test]
  6685. public void SerializeKeyValuePairConverterWithCamelCase()
  6686. {
  6687. string json =
  6688. JsonConvert.SerializeObject(new KeyValuePair<int, string>(123, "test value"), Formatting.Indented, new JsonSerializerSettings
  6689. {
  6690. ContractResolver = new CamelCasePropertyNamesContractResolver()
  6691. });
  6692. Assert.AreEqual(@"{
  6693. ""key"": 123,
  6694. ""value"": ""test value""
  6695. }", json);
  6696. }
  6697. public class EnumerableClass<T> : IEnumerable<T>
  6698. {
  6699. private readonly IList<T> _values;
  6700. public EnumerableClass(IEnumerable<T> values)
  6701. {
  6702. _values = new List<T>(values);
  6703. }
  6704. public IEnumerator<T> GetEnumerator()
  6705. {
  6706. return _values.GetEnumerator();
  6707. }
  6708. IEnumerator IEnumerable.GetEnumerator()
  6709. {
  6710. return GetEnumerator();
  6711. }
  6712. }
  6713. [Test]
  6714. public void DeserializeIEnumerableFromConstructor()
  6715. {
  6716. string json = @"[
  6717. 1,
  6718. 2,
  6719. null
  6720. ]";
  6721. var result = JsonConvert.DeserializeObject<EnumerableClass<int?>>(json);
  6722. Assert.AreEqual(3, result.Count());
  6723. Assert.AreEqual(1, result.ElementAt(0));
  6724. Assert.AreEqual(2, result.ElementAt(1));
  6725. Assert.AreEqual(null, result.ElementAt(2));
  6726. }
  6727. public class EnumerableClassFailure<T> : IEnumerable<T>
  6728. {
  6729. private readonly IList<T> _values;
  6730. public EnumerableClassFailure()
  6731. {
  6732. _values = new List<T>();
  6733. }
  6734. public IEnumerator<T> GetEnumerator()
  6735. {
  6736. return _values.GetEnumerator();
  6737. }
  6738. IEnumerator IEnumerable.GetEnumerator()
  6739. {
  6740. return GetEnumerator();
  6741. }
  6742. }
  6743. [Test]
  6744. public void DeserializeIEnumerableFromConstructor_Failure()
  6745. {
  6746. string json = @"[
  6747. ""One"",
  6748. ""II"",
  6749. ""3""
  6750. ]";
  6751. ExceptionAssert.Throws<JsonSerializationException>(
  6752. "Cannot create and populate list type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+EnumerableClassFailure`1[System.String]. Path '', line 1, position 1.",
  6753. () => JsonConvert.DeserializeObject<EnumerableClassFailure<string>>(json));
  6754. }
  6755. [JsonObject(MemberSerialization.Fields)]
  6756. public class MyTuple<T1>
  6757. {
  6758. private readonly T1 m_Item1;
  6759. public MyTuple(T1 item1)
  6760. {
  6761. m_Item1 = item1;
  6762. }
  6763. public T1 Item1
  6764. {
  6765. get { return m_Item1; }
  6766. }
  6767. }
  6768. [JsonObject(MemberSerialization.Fields)]
  6769. public class MyTuplePartial<T1>
  6770. {
  6771. private readonly T1 m_Item1;
  6772. public MyTuplePartial(T1 item1)
  6773. {
  6774. m_Item1 = item1;
  6775. }
  6776. public T1 Item1
  6777. {
  6778. get { return m_Item1; }
  6779. }
  6780. }
  6781. [Test]
  6782. public void SerializeFloatingPointHandling()
  6783. {
  6784. string json;
  6785. IList<double> d = new List<double> { 1.1, double.NaN, double.PositiveInfinity };
  6786. json = JsonConvert.SerializeObject(d);
  6787. // [1.1,"NaN","Infinity"]
  6788. json = JsonConvert.SerializeObject(d, new JsonSerializerSettings { FloatFormatHandling = FloatFormatHandling.Symbol });
  6789. // [1.1,NaN,Infinity]
  6790. json = JsonConvert.SerializeObject(d, new JsonSerializerSettings { FloatFormatHandling = FloatFormatHandling.DefaultValue });
  6791. // [1.1,0.0,0.0]
  6792. Assert.AreEqual("[1.1,0.0,0.0]", json);
  6793. }
  6794. #if !(NET20 || NET35 || NET40 || PORTABLE40)
  6795. #if !PORTABLE
  6796. [Test]
  6797. public void DeserializeReadOnlyListWithBigInteger()
  6798. {
  6799. string json = @"[
  6800. 9000000000000000000000000000000000000000000000000
  6801. ]";
  6802. var l = JsonConvert.DeserializeObject<IReadOnlyList<BigInteger>>(json);
  6803. BigInteger nineQuindecillion = l[0];
  6804. // 9000000000000000000000000000000000000000000000000
  6805. Assert.AreEqual(BigInteger.Parse("9000000000000000000000000000000000000000000000000"), nineQuindecillion);
  6806. }
  6807. #endif
  6808. [Test]
  6809. public void DeserializeReadOnlyListWithInt()
  6810. {
  6811. string json = @"[
  6812. 900
  6813. ]";
  6814. var l = JsonConvert.DeserializeObject<IReadOnlyList<int>>(json);
  6815. int i = l[0];
  6816. // 900
  6817. Assert.AreEqual(900, i);
  6818. }
  6819. [Test]
  6820. public void DeserializeReadOnlyListWithNullableType()
  6821. {
  6822. string json = @"[
  6823. 1,
  6824. null
  6825. ]";
  6826. var l = JsonConvert.DeserializeObject<IReadOnlyList<int?>>(json);
  6827. Assert.AreEqual(1, l[0]);
  6828. Assert.AreEqual(null, l[1]);
  6829. }
  6830. #endif
  6831. [Test]
  6832. public void SerializeCustomTupleWithSerializableAttribute()
  6833. {
  6834. var tuple = new MyTuple<int>(500);
  6835. var json = JsonConvert.SerializeObject(tuple);
  6836. Assert.AreEqual(@"{""m_Item1"":500}", json);
  6837. MyTuple<int> obj = null;
  6838. Action doStuff = () => { obj = JsonConvert.DeserializeObject<MyTuple<int>>(json); };
  6839. #if !(NETFX_CORE || PORTABLE || PORTABLE40)
  6840. doStuff();
  6841. Assert.AreEqual(500, obj.Item1);
  6842. #else
  6843. ExceptionAssert.Throws<JsonSerializationException>(
  6844. "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuple`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.",
  6845. doStuff);
  6846. #endif
  6847. }
  6848. #if DEBUG
  6849. [Test]
  6850. public void SerializeCustomTupleWithSerializableAttributeInPartialTrust()
  6851. {
  6852. try
  6853. {
  6854. JsonTypeReflector.SetFullyTrusted(false);
  6855. var tuple = new MyTuplePartial<int>(500);
  6856. var json = JsonConvert.SerializeObject(tuple);
  6857. Assert.AreEqual(@"{""m_Item1"":500}", json);
  6858. ExceptionAssert.Throws<JsonSerializationException>(
  6859. "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuplePartial`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.",
  6860. () => JsonConvert.DeserializeObject<MyTuplePartial<int>>(json));
  6861. }
  6862. finally
  6863. {
  6864. JsonTypeReflector.SetFullyTrusted(true);
  6865. }
  6866. }
  6867. #endif
  6868. #if !(NETFX_CORE || PORTABLE || NET35 || NET20 || PORTABLE40)
  6869. [Test]
  6870. public void SerializeTupleWithSerializableAttribute()
  6871. {
  6872. var tuple = Tuple.Create(500);
  6873. var json = JsonConvert.SerializeObject(tuple, new JsonSerializerSettings
  6874. {
  6875. ContractResolver = new SerializableContractResolver()
  6876. });
  6877. Assert.AreEqual(@"{""m_Item1"":500}", json);
  6878. var obj = JsonConvert.DeserializeObject<Tuple<int>>(json, new JsonSerializerSettings
  6879. {
  6880. ContractResolver = new SerializableContractResolver()
  6881. });
  6882. Assert.AreEqual(500, obj.Item1);
  6883. }
  6884. public class SerializableContractResolver : DefaultContractResolver
  6885. {
  6886. public SerializableContractResolver()
  6887. {
  6888. IgnoreSerializableAttribute = false;
  6889. }
  6890. }
  6891. #endif
  6892. #if !(NET40 || NET35 || NET20 || PORTABLE40)
  6893. public class PopulateReadOnlyTestClass
  6894. {
  6895. public IList<int> NonReadOnlyList { get; set; }
  6896. public IDictionary<string, int> NonReadOnlyDictionary { get; set; }
  6897. public IList<int> Array { get; set; }
  6898. public IList<int> List { get; set; }
  6899. public IDictionary<string, int> Dictionary { get; set; }
  6900. public IReadOnlyCollection<int> IReadOnlyCollection { get; set; }
  6901. public ReadOnlyCollection<int> ReadOnlyCollection { get; set; }
  6902. public IReadOnlyList<int> IReadOnlyList { get; set; }
  6903. public IReadOnlyDictionary<string, int> IReadOnlyDictionary { get; set; }
  6904. public ReadOnlyDictionary<string, int> ReadOnlyDictionary { get; set; }
  6905. public PopulateReadOnlyTestClass()
  6906. {
  6907. NonReadOnlyList = new List<int> { 1 };
  6908. NonReadOnlyDictionary = new Dictionary<string, int> { { "first", 2 } };
  6909. Array = new[] { 3 };
  6910. List = new ReadOnlyCollection<int>(new[] { 4 });
  6911. Dictionary = new ReadOnlyDictionary<string, int>(new Dictionary<string, int> { { "first", 5 } });
  6912. IReadOnlyCollection = new ReadOnlyCollection<int>(new[] { 6 });
  6913. ReadOnlyCollection = new ReadOnlyCollection<int>(new[] { 7 });
  6914. IReadOnlyList = new ReadOnlyCollection<int>(new[] { 8 });
  6915. IReadOnlyDictionary = new ReadOnlyDictionary<string, int>(new Dictionary<string, int> { { "first", 9 } });
  6916. ReadOnlyDictionary = new ReadOnlyDictionary<string, int>(new Dictionary<string, int> { { "first", 10 } });
  6917. }
  6918. }
  6919. [Test]
  6920. public void SerializeReadOnlyCollections()
  6921. {
  6922. PopulateReadOnlyTestClass c1 = new PopulateReadOnlyTestClass();
  6923. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  6924. Assert.AreEqual(@"{
  6925. ""NonReadOnlyList"": [
  6926. 1
  6927. ],
  6928. ""NonReadOnlyDictionary"": {
  6929. ""first"": 2
  6930. },
  6931. ""Array"": [
  6932. 3
  6933. ],
  6934. ""List"": [
  6935. 4
  6936. ],
  6937. ""Dictionary"": {
  6938. ""first"": 5
  6939. },
  6940. ""IReadOnlyCollection"": [
  6941. 6
  6942. ],
  6943. ""ReadOnlyCollection"": [
  6944. 7
  6945. ],
  6946. ""IReadOnlyList"": [
  6947. 8
  6948. ],
  6949. ""IReadOnlyDictionary"": {
  6950. ""first"": 9
  6951. },
  6952. ""ReadOnlyDictionary"": {
  6953. ""first"": 10
  6954. }
  6955. }", json);
  6956. }
  6957. [Test]
  6958. public void PopulateReadOnlyCollections()
  6959. {
  6960. string json = @"{
  6961. ""NonReadOnlyList"": [
  6962. 11
  6963. ],
  6964. ""NonReadOnlyDictionary"": {
  6965. ""first"": 12
  6966. },
  6967. ""Array"": [
  6968. 13
  6969. ],
  6970. ""List"": [
  6971. 14
  6972. ],
  6973. ""Dictionary"": {
  6974. ""first"": 15
  6975. },
  6976. ""IReadOnlyCollection"": [
  6977. 16
  6978. ],
  6979. ""ReadOnlyCollection"": [
  6980. 17
  6981. ],
  6982. ""IReadOnlyList"": [
  6983. 18
  6984. ],
  6985. ""IReadOnlyDictionary"": {
  6986. ""first"": 19
  6987. },
  6988. ""ReadOnlyDictionary"": {
  6989. ""first"": 20
  6990. }
  6991. }";
  6992. var c2 = JsonConvert.DeserializeObject<PopulateReadOnlyTestClass>(json);
  6993. Assert.AreEqual(1, c2.NonReadOnlyDictionary.Count);
  6994. Assert.AreEqual(12, c2.NonReadOnlyDictionary["first"]);
  6995. Assert.AreEqual(2, c2.NonReadOnlyList.Count);
  6996. Assert.AreEqual(1, c2.NonReadOnlyList[0]);
  6997. Assert.AreEqual(11, c2.NonReadOnlyList[1]);
  6998. Assert.AreEqual(1, c2.Array.Count);
  6999. Assert.AreEqual(13, c2.Array[0]);
  7000. }
  7001. #endif
  7002. [Test]
  7003. public void SerializeArray2D()
  7004. {
  7005. Array2D aa = new Array2D();
  7006. aa.Before = "Before!";
  7007. aa.After = "After!";
  7008. aa.Coordinates = new[,] { { 1, 1 }, { 1, 2 }, { 2, 1 }, { 2, 2 } };
  7009. string json = JsonConvert.SerializeObject(aa);
  7010. Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json);
  7011. }
  7012. [Test]
  7013. public void SerializeArray3D()
  7014. {
  7015. Array3D aa = new Array3D();
  7016. aa.Before = "Before!";
  7017. aa.After = "After!";
  7018. aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } };
  7019. string json = JsonConvert.SerializeObject(aa);
  7020. Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}", json);
  7021. }
  7022. [Test]
  7023. public void SerializeArray3DWithConverter()
  7024. {
  7025. Array3DWithConverter aa = new Array3DWithConverter();
  7026. aa.Before = "Before!";
  7027. aa.After = "After!";
  7028. aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } };
  7029. string json = JsonConvert.SerializeObject(aa, Formatting.Indented);
  7030. Assert.AreEqual(@"{
  7031. ""Before"": ""Before!"",
  7032. ""Coordinates"": [
  7033. [
  7034. [
  7035. 1.0,
  7036. 1.0,
  7037. 1.0
  7038. ],
  7039. [
  7040. 1.0,
  7041. 1.0,
  7042. 2.0
  7043. ]
  7044. ],
  7045. [
  7046. [
  7047. 1.0,
  7048. 2.0,
  7049. 1.0
  7050. ],
  7051. [
  7052. 1.0,
  7053. 2.0,
  7054. 2.0
  7055. ]
  7056. ],
  7057. [
  7058. [
  7059. 2.0,
  7060. 1.0,
  7061. 1.0
  7062. ],
  7063. [
  7064. 2.0,
  7065. 1.0,
  7066. 2.0
  7067. ]
  7068. ],
  7069. [
  7070. [
  7071. 2.0,
  7072. 2.0,
  7073. 1.0
  7074. ],
  7075. [
  7076. 2.0,
  7077. 2.0,
  7078. 2.0
  7079. ]
  7080. ]
  7081. ],
  7082. ""After"": ""After!""
  7083. }", json);
  7084. }
  7085. [Test]
  7086. public void DeserializeArray3DWithConverter()
  7087. {
  7088. string json = @"{
  7089. ""Before"": ""Before!"",
  7090. ""Coordinates"": [
  7091. [
  7092. [
  7093. 1.0,
  7094. 1.0,
  7095. 1.0
  7096. ],
  7097. [
  7098. 1.0,
  7099. 1.0,
  7100. 2.0
  7101. ]
  7102. ],
  7103. [
  7104. [
  7105. 1.0,
  7106. 2.0,
  7107. 1.0
  7108. ],
  7109. [
  7110. 1.0,
  7111. 2.0,
  7112. 2.0
  7113. ]
  7114. ],
  7115. [
  7116. [
  7117. 2.0,
  7118. 1.0,
  7119. 1.0
  7120. ],
  7121. [
  7122. 2.0,
  7123. 1.0,
  7124. 2.0
  7125. ]
  7126. ],
  7127. [
  7128. [
  7129. 2.0,
  7130. 2.0,
  7131. 1.0
  7132. ],
  7133. [
  7134. 2.0,
  7135. 2.0,
  7136. 2.0
  7137. ]
  7138. ]
  7139. ],
  7140. ""After"": ""After!""
  7141. }";
  7142. Array3DWithConverter aa = JsonConvert.DeserializeObject<Array3DWithConverter>(json);
  7143. Assert.AreEqual("Before!", aa.Before);
  7144. Assert.AreEqual("After!", aa.After);
  7145. Assert.AreEqual(4, aa.Coordinates.GetLength(0));
  7146. Assert.AreEqual(2, aa.Coordinates.GetLength(1));
  7147. Assert.AreEqual(3, aa.Coordinates.GetLength(2));
  7148. Assert.AreEqual(1, aa.Coordinates[0, 0, 0]);
  7149. Assert.AreEqual(2, aa.Coordinates[1, 1, 1]);
  7150. }
  7151. [Test]
  7152. public void DeserializeArray2D()
  7153. {
  7154. string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}";
  7155. Array2D aa = JsonConvert.DeserializeObject<Array2D>(json);
  7156. Assert.AreEqual("Before!", aa.Before);
  7157. Assert.AreEqual("After!", aa.After);
  7158. Assert.AreEqual(4, aa.Coordinates.GetLength(0));
  7159. Assert.AreEqual(2, aa.Coordinates.GetLength(1));
  7160. Assert.AreEqual(1, aa.Coordinates[0, 0]);
  7161. Assert.AreEqual(2, aa.Coordinates[1, 1]);
  7162. string after = JsonConvert.SerializeObject(aa);
  7163. Assert.AreEqual(json, after);
  7164. }
  7165. [Test]
  7166. public void DeserializeArray2D_WithTooManyItems()
  7167. {
  7168. string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2,3],[2,1],[2,2]],""After"":""After!""}";
  7169. ExceptionAssert.Throws<Exception>(
  7170. "Cannot deserialize non-cubical array as multidimensional array.",
  7171. () => JsonConvert.DeserializeObject<Array2D>(json));
  7172. }
  7173. [Test]
  7174. public void DeserializeArray2D_WithTooFewItems()
  7175. {
  7176. string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1],[2,1],[2,2]],""After"":""After!""}";
  7177. ExceptionAssert.Throws<Exception>(
  7178. "Cannot deserialize non-cubical array as multidimensional array.",
  7179. () => JsonConvert.DeserializeObject<Array2D>(json));
  7180. }
  7181. [Test]
  7182. public void DeserializeArray3D()
  7183. {
  7184. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}";
  7185. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  7186. Assert.AreEqual("Before!", aa.Before);
  7187. Assert.AreEqual("After!", aa.After);
  7188. Assert.AreEqual(4, aa.Coordinates.GetLength(0));
  7189. Assert.AreEqual(2, aa.Coordinates.GetLength(1));
  7190. Assert.AreEqual(3, aa.Coordinates.GetLength(2));
  7191. Assert.AreEqual(1, aa.Coordinates[0, 0, 0]);
  7192. Assert.AreEqual(2, aa.Coordinates[1, 1, 1]);
  7193. string after = JsonConvert.SerializeObject(aa);
  7194. Assert.AreEqual(json, after);
  7195. }
  7196. [Test]
  7197. public void DeserializeArray3D_WithTooManyItems()
  7198. {
  7199. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}";
  7200. ExceptionAssert.Throws<Exception>(
  7201. "Cannot deserialize non-cubical array as multidimensional array.",
  7202. () => JsonConvert.DeserializeObject<Array3D>(json));
  7203. }
  7204. [Test]
  7205. public void DeserializeArray3D_WithBadItems()
  7206. {
  7207. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],{}]],""After"":""After!""}";
  7208. ExceptionAssert.Throws<JsonSerializationException>(
  7209. "Unexpected token when deserializing multidimensional array: StartObject. Path 'Coordinates[3][1]', line 1, position 99.",
  7210. () => JsonConvert.DeserializeObject<Array3D>(json));
  7211. }
  7212. [Test]
  7213. public void DeserializeArray3D_WithTooFewItems()
  7214. {
  7215. string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}";
  7216. ExceptionAssert.Throws<Exception>(
  7217. "Cannot deserialize non-cubical array as multidimensional array.",
  7218. () => JsonConvert.DeserializeObject<Array3D>(json));
  7219. }
  7220. [Test]
  7221. public void SerializeEmpty3DArray()
  7222. {
  7223. Array3D aa = new Array3D();
  7224. aa.Before = "Before!";
  7225. aa.After = "After!";
  7226. aa.Coordinates = new int[0, 0, 0];
  7227. string json = JsonConvert.SerializeObject(aa);
  7228. Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}", json);
  7229. }
  7230. [Test]
  7231. public void DeserializeEmpty3DArray()
  7232. {
  7233. string json = @"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}";
  7234. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  7235. Assert.AreEqual("Before!", aa.Before);
  7236. Assert.AreEqual("After!", aa.After);
  7237. Assert.AreEqual(0, aa.Coordinates.GetLength(0));
  7238. Assert.AreEqual(0, aa.Coordinates.GetLength(1));
  7239. Assert.AreEqual(0, aa.Coordinates.GetLength(2));
  7240. string after = JsonConvert.SerializeObject(aa);
  7241. Assert.AreEqual(json, after);
  7242. }
  7243. [Test]
  7244. public void DeserializeIncomplete3DArray()
  7245. {
  7246. string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/[1/*hi*/,/*hi*/1/*hi*/,1]/*hi*/,/*hi*/[1,1";
  7247. ExceptionAssert.Throws<JsonException>(
  7248. null,
  7249. () => JsonConvert.DeserializeObject<Array3D>(json));
  7250. }
  7251. [Test]
  7252. public void DeserializeIncompleteNotTopLevel3DArray()
  7253. {
  7254. string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/";
  7255. ExceptionAssert.Throws<JsonException>(
  7256. null,
  7257. () => JsonConvert.DeserializeObject<Array3D>(json));
  7258. }
  7259. [Test]
  7260. public void DeserializeNull3DArray()
  7261. {
  7262. string json = @"{""Before"":""Before!"",""Coordinates"":null,""After"":""After!""}";
  7263. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  7264. Assert.AreEqual("Before!", aa.Before);
  7265. Assert.AreEqual("After!", aa.After);
  7266. Assert.AreEqual(null, aa.Coordinates);
  7267. string after = JsonConvert.SerializeObject(aa);
  7268. Assert.AreEqual(json, after);
  7269. }
  7270. [Test]
  7271. public void DeserializeSemiEmpty3DArray()
  7272. {
  7273. string json = @"{""Before"":""Before!"",""Coordinates"":[[]],""After"":""After!""}";
  7274. Array3D aa = JsonConvert.DeserializeObject<Array3D>(json);
  7275. Assert.AreEqual("Before!", aa.Before);
  7276. Assert.AreEqual("After!", aa.After);
  7277. Assert.AreEqual(1, aa.Coordinates.GetLength(0));
  7278. Assert.AreEqual(0, aa.Coordinates.GetLength(1));
  7279. Assert.AreEqual(0, aa.Coordinates.GetLength(2));
  7280. string after = JsonConvert.SerializeObject(aa);
  7281. Assert.AreEqual(json, after);
  7282. }
  7283. [Test]
  7284. public void SerializeReferenceTracked3DArray()
  7285. {
  7286. Event e1 = new Event
  7287. {
  7288. EventName = "EventName!"
  7289. };
  7290. Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } };
  7291. IList<Event[,]> values1 = new List<Event[,]>
  7292. {
  7293. array1,
  7294. array1
  7295. };
  7296. string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings
  7297. {
  7298. PreserveReferencesHandling = PreserveReferencesHandling.All,
  7299. Formatting = Formatting.Indented
  7300. });
  7301. Assert.AreEqual(@"{
  7302. ""$id"": ""1"",
  7303. ""$values"": [
  7304. {
  7305. ""$id"": ""2"",
  7306. ""$values"": [
  7307. [
  7308. {
  7309. ""$id"": ""3"",
  7310. ""EventName"": ""EventName!"",
  7311. ""Venue"": null,
  7312. ""Performances"": null
  7313. },
  7314. {
  7315. ""$ref"": ""3""
  7316. }
  7317. ],
  7318. [
  7319. {
  7320. ""$ref"": ""3""
  7321. },
  7322. {
  7323. ""$ref"": ""3""
  7324. }
  7325. ]
  7326. ]
  7327. },
  7328. {
  7329. ""$ref"": ""2""
  7330. }
  7331. ]
  7332. }", json);
  7333. }
  7334. [Test]
  7335. public void SerializeTypeName3DArray()
  7336. {
  7337. Event e1 = new Event
  7338. {
  7339. EventName = "EventName!"
  7340. };
  7341. Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } };
  7342. IList<Event[,]> values1 = new List<Event[,]>
  7343. {
  7344. array1,
  7345. array1
  7346. };
  7347. string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings
  7348. {
  7349. TypeNameHandling = TypeNameHandling.All,
  7350. Formatting = Formatting.Indented
  7351. });
  7352. Assert.AreEqual(@"{
  7353. ""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests]], mscorlib"",
  7354. ""$values"": [
  7355. {
  7356. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests"",
  7357. ""$values"": [
  7358. [
  7359. {
  7360. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7361. ""EventName"": ""EventName!"",
  7362. ""Venue"": null,
  7363. ""Performances"": null
  7364. },
  7365. {
  7366. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7367. ""EventName"": ""EventName!"",
  7368. ""Venue"": null,
  7369. ""Performances"": null
  7370. }
  7371. ],
  7372. [
  7373. {
  7374. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7375. ""EventName"": ""EventName!"",
  7376. ""Venue"": null,
  7377. ""Performances"": null
  7378. },
  7379. {
  7380. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7381. ""EventName"": ""EventName!"",
  7382. ""Venue"": null,
  7383. ""Performances"": null
  7384. }
  7385. ]
  7386. ]
  7387. },
  7388. {
  7389. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests"",
  7390. ""$values"": [
  7391. [
  7392. {
  7393. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7394. ""EventName"": ""EventName!"",
  7395. ""Venue"": null,
  7396. ""Performances"": null
  7397. },
  7398. {
  7399. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7400. ""EventName"": ""EventName!"",
  7401. ""Venue"": null,
  7402. ""Performances"": null
  7403. }
  7404. ],
  7405. [
  7406. {
  7407. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7408. ""EventName"": ""EventName!"",
  7409. ""Venue"": null,
  7410. ""Performances"": null
  7411. },
  7412. {
  7413. ""$type"": ""Newtonsoft.Json.Tests.Serialization.Event, Newtonsoft.Json.Tests"",
  7414. ""EventName"": ""EventName!"",
  7415. ""Venue"": null,
  7416. ""Performances"": null
  7417. }
  7418. ]
  7419. ]
  7420. }
  7421. ]
  7422. }", json);
  7423. IList<Event[,]> values2 = (IList<Event[,]>)JsonConvert.DeserializeObject(json, new JsonSerializerSettings
  7424. {
  7425. TypeNameHandling = TypeNameHandling.All
  7426. });
  7427. Assert.AreEqual(2, values2.Count);
  7428. Assert.AreEqual("EventName!", values2[0][0, 0].EventName);
  7429. }
  7430. public class ExtensionDataDeserializeWithNonDefaultConstructor
  7431. {
  7432. public ExtensionDataDeserializeWithNonDefaultConstructor(string name)
  7433. {
  7434. Name = name;
  7435. }
  7436. [JsonExtensionData]
  7437. public IDictionary<string, JToken> _extensionData;
  7438. public string Name { get; set; }
  7439. }
  7440. [Test]
  7441. public void ExtensionDataDeserializeWithNonDefaultConstructorTest()
  7442. {
  7443. ExtensionDataDeserializeWithNonDefaultConstructor c = new ExtensionDataDeserializeWithNonDefaultConstructor("Name!");
  7444. c._extensionData = new Dictionary<string, JToken>
  7445. {
  7446. { "Key!", "Value!" }
  7447. };
  7448. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  7449. Assert.AreEqual(@"{
  7450. ""Name"": ""Name!"",
  7451. ""Key!"": ""Value!""
  7452. }", json);
  7453. var c2 = JsonConvert.DeserializeObject<ExtensionDataDeserializeWithNonDefaultConstructor>(json);
  7454. Assert.AreEqual("Name!", c2.Name);
  7455. Assert.IsNotNull(c2._extensionData);
  7456. Assert.AreEqual(1, c2._extensionData.Count);
  7457. Assert.AreEqual("Value!", (string)c2._extensionData["Key!"]);
  7458. }
  7459. #if NETFX_CORE
  7460. [Test]
  7461. public void SerializeWinRTJsonObject()
  7462. {
  7463. var o = Windows.Data.Json.JsonObject.Parse(@"{
  7464. ""CPU"": ""Intel"",
  7465. ""Drives"": [
  7466. ""DVD read/writer"",
  7467. ""500 gigabyte hard drive""
  7468. ]
  7469. }");
  7470. string json = JsonConvert.SerializeObject(o, Formatting.Indented);
  7471. Assert.AreEqual(@"{
  7472. ""Drives"": [
  7473. ""DVD read/writer"",
  7474. ""500 gigabyte hard drive""
  7475. ],
  7476. ""CPU"": ""Intel""
  7477. }", json);
  7478. }
  7479. #endif
  7480. #if !NET20
  7481. [Test]
  7482. public void RoundtripOfDateTimeOffset()
  7483. {
  7484. var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}";
  7485. var jsonSerializerSettings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind };
  7486. var obj = (JObject)JsonConvert.DeserializeObject(content, jsonSerializerSettings);
  7487. var dateTimeOffset = (DateTimeOffset)((JValue)obj["startDateTime"]).Value;
  7488. Assert.AreEqual(TimeSpan.FromHours(9.5), dateTimeOffset.Offset);
  7489. Assert.AreEqual("07/19/2012 14:30:00 +09:30", dateTimeOffset.ToString(CultureInfo.InvariantCulture));
  7490. }
  7491. public class NullableFloats
  7492. {
  7493. public object Object { get; set; }
  7494. public float Float { get; set; }
  7495. public double Double { get; set; }
  7496. public float? NullableFloat { get; set; }
  7497. public double? NullableDouble { get; set; }
  7498. public object ObjectNull { get; set; }
  7499. }
  7500. [Test]
  7501. public void NullableFloatingPoint()
  7502. {
  7503. NullableFloats floats = new NullableFloats
  7504. {
  7505. Object = double.NaN,
  7506. ObjectNull = null,
  7507. Float = float.NaN,
  7508. NullableDouble = double.NaN,
  7509. NullableFloat = null
  7510. };
  7511. string json = JsonConvert.SerializeObject(floats, Formatting.Indented, new JsonSerializerSettings
  7512. {
  7513. FloatFormatHandling = FloatFormatHandling.DefaultValue
  7514. });
  7515. Assert.AreEqual(@"{
  7516. ""Object"": 0.0,
  7517. ""Float"": 0.0,
  7518. ""Double"": 0.0,
  7519. ""NullableFloat"": null,
  7520. ""NullableDouble"": null,
  7521. ""ObjectNull"": null
  7522. }", json);
  7523. }
  7524. [Test]
  7525. public void DateFormatString()
  7526. {
  7527. IList<object> dates = new List<object>
  7528. {
  7529. new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc),
  7530. new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1))
  7531. };
  7532. string json = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings
  7533. {
  7534. DateFormatString = "yyyy tt",
  7535. Culture = new CultureInfo("en-NZ")
  7536. });
  7537. Assert.AreEqual(@"[
  7538. ""2000 p.m."",
  7539. ""2000 p.m.""
  7540. ]", json);
  7541. }
  7542. [Test]
  7543. public void DateFormatStringForInternetExplorer()
  7544. {
  7545. IList<object> dates = new List<object>
  7546. {
  7547. new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc),
  7548. new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1))
  7549. };
  7550. string json = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings
  7551. {
  7552. DateFormatString = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffK"
  7553. });
  7554. Assert.AreEqual(@"[
  7555. ""2000-12-12T12:12:12.000Z"",
  7556. ""2000-12-12T12:12:12.000+01:00""
  7557. ]", json);
  7558. }
  7559. [Test]
  7560. public void JsonSerializerDateFormatString()
  7561. {
  7562. IList<object> dates = new List<object>
  7563. {
  7564. new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc),
  7565. new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1))
  7566. };
  7567. StringWriter sw = new StringWriter();
  7568. JsonTextWriter jsonWriter = new JsonTextWriter(sw);
  7569. JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings
  7570. {
  7571. DateFormatString = "yyyy tt",
  7572. Culture = new CultureInfo("en-NZ"),
  7573. Formatting = Formatting.Indented
  7574. });
  7575. serializer.Serialize(jsonWriter, dates);
  7576. Assert.IsNull(jsonWriter.DateFormatString);
  7577. Assert.AreEqual(CultureInfo.InvariantCulture, jsonWriter.Culture);
  7578. Assert.AreEqual(Formatting.None, jsonWriter.Formatting);
  7579. string json = sw.ToString();
  7580. Assert.AreEqual(@"[
  7581. ""2000 p.m."",
  7582. ""2000 p.m.""
  7583. ]", json);
  7584. }
  7585. #if !(NET20 || NET35)
  7586. [Test]
  7587. public void SerializeDeserializeTuple()
  7588. {
  7589. Tuple<int, int> tuple = Tuple.Create(500, 20);
  7590. string json = JsonConvert.SerializeObject(tuple);
  7591. Assert.AreEqual(@"{""Item1"":500,""Item2"":20}", json);
  7592. Tuple<int, int> tuple2 = JsonConvert.DeserializeObject<Tuple<int, int>>(json);
  7593. Assert.AreEqual(500, tuple2.Item1);
  7594. Assert.AreEqual(20, tuple2.Item2);
  7595. }
  7596. #endif
  7597. public class MessageWithIsoDate
  7598. {
  7599. public String IsoDate { get; set; }
  7600. }
  7601. [Test]
  7602. public void JsonSerializerStringEscapeHandling()
  7603. {
  7604. StringWriter sw = new StringWriter();
  7605. JsonTextWriter jsonWriter = new JsonTextWriter(sw);
  7606. JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings
  7607. {
  7608. StringEscapeHandling = StringEscapeHandling.EscapeHtml,
  7609. Formatting = Formatting.Indented
  7610. });
  7611. serializer.Serialize(jsonWriter, new { html = "<html></html>" });
  7612. Assert.AreEqual(StringEscapeHandling.Default, jsonWriter.StringEscapeHandling);
  7613. string json = sw.ToString();
  7614. Assert.AreEqual(@"{
  7615. ""html"": ""\u003chtml\u003e\u003c/html\u003e""
  7616. }", json);
  7617. }
  7618. public class NoConstructorReadOnlyCollection<T> : ReadOnlyCollection<T>
  7619. {
  7620. public NoConstructorReadOnlyCollection() : base(new List<T>())
  7621. {
  7622. }
  7623. }
  7624. [Test]
  7625. public void NoConstructorReadOnlyCollectionTest()
  7626. {
  7627. ExceptionAssert.Throws<JsonSerializationException>(
  7628. "Cannot deserialize readonly or fixed size list: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+NoConstructorReadOnlyCollection`1[System.Int32]. Path '', line 1, position 1.",
  7629. () => JsonConvert.DeserializeObject<NoConstructorReadOnlyCollection<int>>("[1]"));
  7630. }
  7631. #if !(NET40 || NET35 || NET20 || PORTABLE40)
  7632. public class NoConstructorReadOnlyDictionary<TKey, TValue> : ReadOnlyDictionary<TKey, TValue>
  7633. {
  7634. public NoConstructorReadOnlyDictionary()
  7635. : base(new Dictionary<TKey, TValue>())
  7636. {
  7637. }
  7638. }
  7639. [Test]
  7640. public void NoConstructorReadOnlyDictionaryTest()
  7641. {
  7642. ExceptionAssert.Throws<JsonSerializationException>(
  7643. "Cannot deserialize readonly or fixed size dictionary: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+NoConstructorReadOnlyDictionary`2[System.Int32,System.Int32]. Path '1', line 1, position 5.",
  7644. () => JsonConvert.DeserializeObject<NoConstructorReadOnlyDictionary<int, int>>("{'1':1}"));
  7645. }
  7646. #endif
  7647. #if !(PORTABLE || NET35 || NET20 || PORTABLE40)
  7648. [Test]
  7649. public void ReadTooLargeInteger()
  7650. {
  7651. string json = @"[999999999999999999999999999999999999999999999999]";
  7652. IList<BigInteger> l = JsonConvert.DeserializeObject<IList<BigInteger>>(json);
  7653. Assert.AreEqual(BigInteger.Parse("999999999999999999999999999999999999999999999999"), l[0]);
  7654. ExceptionAssert.Throws<JsonSerializationException>(
  7655. "Error converting value 999999999999999999999999999999999999999999999999 to type 'System.Int64'. Path '[0]', line 1, position 49.",
  7656. () => JsonConvert.DeserializeObject<IList<long>>(json));
  7657. }
  7658. #endif
  7659. [Test]
  7660. public void ReadStringFloatingPointSymbols()
  7661. {
  7662. string json = @"[
  7663. ""NaN"",
  7664. ""Infinity"",
  7665. ""-Infinity""
  7666. ]";
  7667. IList<float> floats = JsonConvert.DeserializeObject<IList<float>>(json);
  7668. Assert.AreEqual(float.NaN, floats[0]);
  7669. Assert.AreEqual(float.PositiveInfinity, floats[1]);
  7670. Assert.AreEqual(float.NegativeInfinity, floats[2]);
  7671. IList<double> doubles = JsonConvert.DeserializeObject<IList<double>>(json);
  7672. Assert.AreEqual(float.NaN, doubles[0]);
  7673. Assert.AreEqual(float.PositiveInfinity, doubles[1]);
  7674. Assert.AreEqual(float.NegativeInfinity, doubles[2]);
  7675. }
  7676. [Test]
  7677. public void DefaultDateStringFormatVsUnsetDateStringFormat()
  7678. {
  7679. IDictionary<string, object> dates = new Dictionary<string, object>
  7680. {
  7681. { "DateTime-Unspecified", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Unspecified) },
  7682. { "DateTime-Utc", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc) },
  7683. { "DateTime-Local", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Local) },
  7684. { "DateTimeOffset-Zero", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero) },
  7685. { "DateTimeOffset-Plus1", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) },
  7686. { "DateTimeOffset-Plus15", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1.5)) }
  7687. };
  7688. string expected = JsonConvert.SerializeObject(dates, Formatting.Indented);
  7689. Console.WriteLine(expected);
  7690. string actual = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings
  7691. {
  7692. DateFormatString = JsonSerializerSettings.DefaultDateFormatString
  7693. });
  7694. Console.WriteLine(expected);
  7695. Assert.AreEqual(expected, actual);
  7696. }
  7697. #endif
  7698. #if !NET20
  7699. public class NullableTestClass
  7700. {
  7701. public bool? MyNullableBool { get; set; }
  7702. public int? MyNullableInteger { get; set; }
  7703. public DateTime? MyNullableDateTime { get; set; }
  7704. public DateTimeOffset? MyNullableDateTimeOffset { get; set; }
  7705. public Decimal? MyNullableDecimal { get; set; }
  7706. }
  7707. [Test]
  7708. public void TestStringToNullableDeserialization()
  7709. {
  7710. string json = @"{
  7711. ""MyNullableBool"": """",
  7712. ""MyNullableInteger"": """",
  7713. ""MyNullableDateTime"": """",
  7714. ""MyNullableDateTimeOffset"": """",
  7715. ""MyNullableDecimal"": """"
  7716. }";
  7717. NullableTestClass c2 = JsonConvert.DeserializeObject<NullableTestClass>(json);
  7718. Assert.IsNull(c2.MyNullableBool);
  7719. Assert.IsNull(c2.MyNullableInteger);
  7720. Assert.IsNull(c2.MyNullableDateTime);
  7721. Assert.IsNull(c2.MyNullableDateTimeOffset);
  7722. Assert.IsNull(c2.MyNullableDecimal);
  7723. }
  7724. #endif
  7725. #if !(NET20 || NET35 || PORTABLE40)
  7726. [Test]
  7727. public void HashSetInterface()
  7728. {
  7729. ISet<string> s1 = new HashSet<string>(new[] { "1", "two", "III" });
  7730. string json = JsonConvert.SerializeObject(s1);
  7731. ISet<string> s2 = JsonConvert.DeserializeObject<ISet<string>>(json);
  7732. Assert.AreEqual(s1.Count, s2.Count);
  7733. foreach (string s in s1)
  7734. {
  7735. Assert.IsTrue(s2.Contains(s));
  7736. }
  7737. }
  7738. #endif
  7739. public class NewEmployee : Employee
  7740. {
  7741. public int Age { get; set; }
  7742. public bool ShouldSerializeName()
  7743. {
  7744. return false;
  7745. }
  7746. }
  7747. [Test]
  7748. public void ShouldSerializeInheritedClassTest()
  7749. {
  7750. NewEmployee joe = new NewEmployee();
  7751. joe.Name = "Joe Employee";
  7752. joe.Age = 100;
  7753. Employee mike = new Employee();
  7754. mike.Name = "Mike Manager";
  7755. mike.Manager = mike;
  7756. joe.Manager = mike;
  7757. //StringWriter sw = new StringWriter();
  7758. //XmlSerializer x = new XmlSerializer(typeof(NewEmployee));
  7759. //x.Serialize(sw, joe);
  7760. //Console.WriteLine(sw);
  7761. //JavaScriptSerializer s = new JavaScriptSerializer();
  7762. //Console.WriteLine(s.Serialize(new {html = @"<script>hi</script>; & ! ^ * ( ) ! @ # $ % ^ ' "" - , . / ; : [ { } ] ; ' - _ = + ? ` ~ \ |"}));
  7763. string json = JsonConvert.SerializeObject(joe, Formatting.Indented);
  7764. Assert.AreEqual(@"{
  7765. ""Age"": 100,
  7766. ""Name"": ""Joe Employee"",
  7767. ""Manager"": {
  7768. ""Name"": ""Mike Manager""
  7769. }
  7770. }", json);
  7771. }
  7772. [Test]
  7773. public void DeserializeDecimal()
  7774. {
  7775. JsonTextReader reader = new JsonTextReader(new StringReader("1234567890.123456"));
  7776. var settings = new JsonSerializerSettings();
  7777. var serialiser = JsonSerializer.Create(settings);
  7778. decimal? d = serialiser.Deserialize<decimal?>(reader);
  7779. Assert.AreEqual(1234567890.123456m, d);
  7780. }
  7781. #if !(PORTABLE || NETFX_CORE || PORTABLE40)
  7782. [Test]
  7783. public void DontSerializeStaticFields()
  7784. {
  7785. string json =
  7786. JsonConvert.SerializeObject(new AnswerFilterModel(), Formatting.Indented, new JsonSerializerSettings
  7787. {
  7788. ContractResolver = new DefaultContractResolver
  7789. {
  7790. IgnoreSerializableAttribute = false
  7791. }
  7792. });
  7793. Assert.AreEqual(@"{
  7794. ""<Active>k__BackingField"": false,
  7795. ""<Ja>k__BackingField"": false,
  7796. ""<Handlungsbedarf>k__BackingField"": false,
  7797. ""<Beratungsbedarf>k__BackingField"": false,
  7798. ""<Unzutreffend>k__BackingField"": false,
  7799. ""<Unbeantwortet>k__BackingField"": false
  7800. }", json);
  7801. }
  7802. #endif
  7803. [Test]
  7804. public void DeserializeNonGenericList()
  7805. {
  7806. IList l = JsonConvert.DeserializeObject<IList>("['string!']");
  7807. Assert.AreEqual(typeof(List<object>), l.GetType());
  7808. Assert.AreEqual(1, l.Count);
  7809. Assert.AreEqual("string!", l[0]);
  7810. }
  7811. #if !(NET20 || NET35 || PORTABLE || PORTABLE40)
  7812. [Test]
  7813. public void SerializeBigInteger()
  7814. {
  7815. BigInteger i = BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990");
  7816. string json = JsonConvert.SerializeObject(new[] { i }, Formatting.Indented);
  7817. Assert.AreEqual(@"[
  7818. 123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990
  7819. ]", json);
  7820. }
  7821. #endif
  7822. #if !(NET40 || NET35 || NET20 || PORTABLE40)
  7823. [Test]
  7824. public void DeserializeReadOnlyListInterface()
  7825. {
  7826. IReadOnlyList<int> list = JsonConvert.DeserializeObject<IReadOnlyList<int>>("[1,2,3]");
  7827. Assert.AreEqual(3, list.Count);
  7828. Assert.AreEqual(1, list[0]);
  7829. Assert.AreEqual(2, list[1]);
  7830. Assert.AreEqual(3, list[2]);
  7831. }
  7832. [Test]
  7833. public void DeserializeReadOnlyCollectionInterface()
  7834. {
  7835. IReadOnlyCollection<int> list = JsonConvert.DeserializeObject<IReadOnlyCollection<int>>("[1,2,3]");
  7836. Assert.AreEqual(3, list.Count);
  7837. Assert.AreEqual(1, list.ElementAt(0));
  7838. Assert.AreEqual(2, list.ElementAt(1));
  7839. Assert.AreEqual(3, list.ElementAt(2));
  7840. }
  7841. [Test]
  7842. public void DeserializeReadOnlyCollection()
  7843. {
  7844. ReadOnlyCollection<int> list = JsonConvert.DeserializeObject<ReadOnlyCollection<int>>("[1,2,3]");
  7845. Assert.AreEqual(3, list.Count);
  7846. Assert.AreEqual(1, list[0]);
  7847. Assert.AreEqual(2, list[1]);
  7848. Assert.AreEqual(3, list[2]);
  7849. }
  7850. [Test]
  7851. public void DeserializeReadOnlyDictionaryInterface()
  7852. {
  7853. IReadOnlyDictionary<string, int> dic = JsonConvert.DeserializeObject<IReadOnlyDictionary<string, int>>("{'one':1,'two':2}");
  7854. Assert.AreEqual(2, dic.Count);
  7855. Assert.AreEqual(1, dic["one"]);
  7856. Assert.AreEqual(2, dic["two"]);
  7857. CustomAssert.IsInstanceOfType(typeof(ReadOnlyDictionary<string, int>), dic);
  7858. }
  7859. [Test]
  7860. public void DeserializeReadOnlyDictionary()
  7861. {
  7862. ReadOnlyDictionary<string, int> dic = JsonConvert.DeserializeObject<ReadOnlyDictionary<string, int>>("{'one':1,'two':2}");
  7863. Assert.AreEqual(2, dic.Count);
  7864. Assert.AreEqual(1, dic["one"]);
  7865. Assert.AreEqual(2, dic["two"]);
  7866. }
  7867. public class CustomReadOnlyDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>
  7868. {
  7869. private readonly IDictionary<TKey, TValue> _dictionary;
  7870. public CustomReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
  7871. {
  7872. _dictionary = dictionary;
  7873. }
  7874. public bool ContainsKey(TKey key)
  7875. {
  7876. return _dictionary.ContainsKey(key);
  7877. }
  7878. public IEnumerable<TKey> Keys
  7879. {
  7880. get { return _dictionary.Keys; }
  7881. }
  7882. public bool TryGetValue(TKey key, out TValue value)
  7883. {
  7884. return _dictionary.TryGetValue(key, out value);
  7885. }
  7886. public IEnumerable<TValue> Values
  7887. {
  7888. get { return _dictionary.Values; }
  7889. }
  7890. public TValue this[TKey key]
  7891. {
  7892. get { return _dictionary[key]; }
  7893. }
  7894. public int Count
  7895. {
  7896. get { return _dictionary.Count; }
  7897. }
  7898. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
  7899. {
  7900. return _dictionary.GetEnumerator();
  7901. }
  7902. IEnumerator IEnumerable.GetEnumerator()
  7903. {
  7904. return _dictionary.GetEnumerator();
  7905. }
  7906. }
  7907. [Test]
  7908. public void SerializeCustomReadOnlyDictionary()
  7909. {
  7910. IDictionary<string, int> d = new Dictionary<string, int>
  7911. {
  7912. { "one", 1 },
  7913. { "two", 2 }
  7914. };
  7915. CustomReadOnlyDictionary<string, int> dic = new CustomReadOnlyDictionary<string, int>(d);
  7916. string json = JsonConvert.SerializeObject(dic, Formatting.Indented);
  7917. Assert.AreEqual(@"{
  7918. ""one"": 1,
  7919. ""two"": 2
  7920. }", json);
  7921. }
  7922. public class CustomReadOnlyCollection<T> : IReadOnlyCollection<T>
  7923. {
  7924. private readonly IList<T> _values;
  7925. public CustomReadOnlyCollection(IList<T> values)
  7926. {
  7927. _values = values;
  7928. }
  7929. public int Count
  7930. {
  7931. get { return _values.Count; }
  7932. }
  7933. public IEnumerator<T> GetEnumerator()
  7934. {
  7935. return _values.GetEnumerator();
  7936. }
  7937. IEnumerator IEnumerable.GetEnumerator()
  7938. {
  7939. return _values.GetEnumerator();
  7940. }
  7941. }
  7942. [Test]
  7943. public void SerializeCustomReadOnlyCollection()
  7944. {
  7945. IList<int> l = new List<int>
  7946. {
  7947. 1,
  7948. 2,
  7949. 3
  7950. };
  7951. CustomReadOnlyCollection<int> list = new CustomReadOnlyCollection<int>(l);
  7952. string json = JsonConvert.SerializeObject(list, Formatting.Indented);
  7953. Assert.AreEqual(@"[
  7954. 1,
  7955. 2,
  7956. 3
  7957. ]", json);
  7958. }
  7959. #endif
  7960. public class PrivateDefaultCtorList<T> : List<T>
  7961. {
  7962. private PrivateDefaultCtorList()
  7963. {
  7964. }
  7965. }
  7966. [Test]
  7967. public void DeserializePrivateListCtor()
  7968. {
  7969. ExceptionAssert.Throws<JsonSerializationException>(
  7970. "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PrivateDefaultCtorList`1[System.Int32]. Path '', line 1, position 1.",
  7971. () => JsonConvert.DeserializeObject<PrivateDefaultCtorList<int>>("[1,2]")
  7972. );
  7973. var list = JsonConvert.DeserializeObject<PrivateDefaultCtorList<int>>("[1,2]", new JsonSerializerSettings
  7974. {
  7975. ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
  7976. });
  7977. Assert.AreEqual(2, list.Count);
  7978. }
  7979. public class PrivateDefaultCtorWithIEnumerableCtorList<T> : List<T>
  7980. {
  7981. private PrivateDefaultCtorWithIEnumerableCtorList()
  7982. {
  7983. }
  7984. public PrivateDefaultCtorWithIEnumerableCtorList(IEnumerable<T> values)
  7985. : base(values)
  7986. {
  7987. Add(default(T));
  7988. }
  7989. }
  7990. [Test]
  7991. public void DeserializePrivateListConstructor()
  7992. {
  7993. var list = JsonConvert.DeserializeObject<PrivateDefaultCtorWithIEnumerableCtorList<int>>("[1,2]");
  7994. Assert.AreEqual(3, list.Count);
  7995. Assert.AreEqual(1, list[0]);
  7996. Assert.AreEqual(2, list[1]);
  7997. Assert.AreEqual(0, list[2]);
  7998. }
  7999. [Test]
  8000. public void DeserializeNonIsoDateDictionaryKey()
  8001. {
  8002. Dictionary<DateTime, string> d = JsonConvert.DeserializeObject<Dictionary<DateTime, string>>(@"{""04/28/2013 00:00:00"":""test""}");
  8003. Assert.AreEqual(1, d.Count);
  8004. DateTime key = DateTime.Parse("04/28/2013 00:00:00", CultureInfo.InvariantCulture);
  8005. Assert.AreEqual("test", d[key]);
  8006. }
  8007. public class IdReferenceResolver : IReferenceResolver
  8008. {
  8009. private readonly IDictionary<Guid, PersonReference> _people = new Dictionary<Guid, PersonReference>();
  8010. public object ResolveReference(object context, string reference)
  8011. {
  8012. Guid id = new Guid(reference);
  8013. PersonReference p;
  8014. _people.TryGetValue(id, out p);
  8015. return p;
  8016. }
  8017. public string GetReference(object context, object value)
  8018. {
  8019. PersonReference p = (PersonReference)value;
  8020. _people[p.Id] = p;
  8021. return p.Id.ToString();
  8022. }
  8023. public bool IsReferenced(object context, object value)
  8024. {
  8025. PersonReference p = (PersonReference)value;
  8026. return _people.ContainsKey(p.Id);
  8027. }
  8028. public void AddReference(object context, string reference, object value)
  8029. {
  8030. Guid id = new Guid(reference);
  8031. _people[id] = (PersonReference)value;
  8032. }
  8033. }
  8034. [Test]
  8035. public void SerializeCustomReferenceResolver()
  8036. {
  8037. PersonReference john = new PersonReference
  8038. {
  8039. Id = new Guid("0B64FFDF-D155-44AD-9689-58D9ADB137F3"),
  8040. Name = "John Smith"
  8041. };
  8042. PersonReference jane = new PersonReference
  8043. {
  8044. Id = new Guid("AE3C399C-058D-431D-91B0-A36C266441B9"),
  8045. Name = "Jane Smith"
  8046. };
  8047. john.Spouse = jane;
  8048. jane.Spouse = john;
  8049. IList<PersonReference> people = new List<PersonReference>
  8050. {
  8051. john,
  8052. jane
  8053. };
  8054. string json = JsonConvert.SerializeObject(people, new JsonSerializerSettings
  8055. {
  8056. ReferenceResolver = new IdReferenceResolver(),
  8057. PreserveReferencesHandling = PreserveReferencesHandling.Objects,
  8058. Formatting = Formatting.Indented
  8059. });
  8060. Assert.AreEqual(@"[
  8061. {
  8062. ""$id"": ""0b64ffdf-d155-44ad-9689-58d9adb137f3"",
  8063. ""Name"": ""John Smith"",
  8064. ""Spouse"": {
  8065. ""$id"": ""ae3c399c-058d-431d-91b0-a36c266441b9"",
  8066. ""Name"": ""Jane Smith"",
  8067. ""Spouse"": {
  8068. ""$ref"": ""0b64ffdf-d155-44ad-9689-58d9adb137f3""
  8069. }
  8070. }
  8071. },
  8072. {
  8073. ""$ref"": ""ae3c399c-058d-431d-91b0-a36c266441b9""
  8074. }
  8075. ]", json);
  8076. }
  8077. #if !(PORTABLE || PORTABLE40 || NETFX_CORE)
  8078. [Test]
  8079. public void SerializeDictionaryWithStructKey()
  8080. {
  8081. string json = JsonConvert.SerializeObject(
  8082. new Dictionary<Size, Size> { { new Size(1, 2), new Size(3, 4) } }
  8083. );
  8084. Assert.AreEqual(@"{""1, 2"":""3, 4""}", json);
  8085. Dictionary<Size, Size> d = JsonConvert.DeserializeObject<Dictionary<Size, Size>>(json);
  8086. Assert.AreEqual(new Size(1, 2), d.Keys.First());
  8087. Assert.AreEqual(new Size(3, 4), d.Values.First());
  8088. }
  8089. #endif
  8090. [Test]
  8091. public void DeserializeCustomReferenceResolver()
  8092. {
  8093. string json = @"[
  8094. {
  8095. ""$id"": ""0b64ffdf-d155-44ad-9689-58d9adb137f3"",
  8096. ""Name"": ""John Smith"",
  8097. ""Spouse"": {
  8098. ""$id"": ""ae3c399c-058d-431d-91b0-a36c266441b9"",
  8099. ""Name"": ""Jane Smith"",
  8100. ""Spouse"": {
  8101. ""$ref"": ""0b64ffdf-d155-44ad-9689-58d9adb137f3""
  8102. }
  8103. }
  8104. },
  8105. {
  8106. ""$ref"": ""ae3c399c-058d-431d-91b0-a36c266441b9""
  8107. }
  8108. ]";
  8109. IList<PersonReference> people = JsonConvert.DeserializeObject<IList<PersonReference>>(json, new JsonSerializerSettings
  8110. {
  8111. ReferenceResolver = new IdReferenceResolver(),
  8112. PreserveReferencesHandling = PreserveReferencesHandling.Objects,
  8113. Formatting = Formatting.Indented
  8114. });
  8115. Assert.AreEqual(2, people.Count);
  8116. PersonReference john = people[0];
  8117. PersonReference jane = people[1];
  8118. Assert.AreEqual(john, jane.Spouse);
  8119. Assert.AreEqual(jane, john.Spouse);
  8120. }
  8121. #if !(NETFX_CORE || NET35 || NET20 || PORTABLE || PORTABLE40)
  8122. [TypeConverter(typeof(MyInterfaceConverter))]
  8123. internal interface IMyInterface
  8124. {
  8125. string Name { get; }
  8126. string PrintTest();
  8127. }
  8128. internal class MyInterfaceConverter : TypeConverter
  8129. {
  8130. private readonly List<IMyInterface> _writers = new List<IMyInterface>
  8131. {
  8132. new ConsoleWriter(),
  8133. new TraceWriter()
  8134. };
  8135. public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
  8136. {
  8137. return destinationType == typeof(string);
  8138. }
  8139. public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  8140. {
  8141. return sourceType == typeof(string);
  8142. }
  8143. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
  8144. {
  8145. if (value == null)
  8146. return null;
  8147. return (from w in _writers where w.Name == value.ToString() select w).FirstOrDefault();
  8148. }
  8149. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,
  8150. Type destinationType)
  8151. {
  8152. if (value == null)
  8153. return null;
  8154. return ((IMyInterface)value).Name;
  8155. }
  8156. }
  8157. [TypeConverter(typeof(MyInterfaceConverter))]
  8158. internal class ConsoleWriter : IMyInterface
  8159. {
  8160. public string Name
  8161. {
  8162. get { return "Console Writer"; }
  8163. }
  8164. public string PrintTest()
  8165. {
  8166. return "ConsoleWriter";
  8167. }
  8168. public override string ToString()
  8169. {
  8170. return Name;
  8171. }
  8172. }
  8173. internal class TraceWriter : IMyInterface
  8174. {
  8175. public string Name
  8176. {
  8177. get { return "Trace Writer"; }
  8178. }
  8179. public override string ToString()
  8180. {
  8181. return Name;
  8182. }
  8183. public string PrintTest()
  8184. {
  8185. return "TraceWriter";
  8186. }
  8187. }
  8188. internal class TypeConverterJsonConverter : JsonConverter
  8189. {
  8190. private TypeConverter GetConverter(Type type)
  8191. {
  8192. var converters = type.GetCustomAttributes(typeof(TypeConverterAttribute), true).Union(
  8193. from t in type.GetInterfaces()
  8194. from c in t.GetCustomAttributes(typeof(TypeConverterAttribute), true)
  8195. select c).Distinct();
  8196. return
  8197. (from c in converters
  8198. let converter =
  8199. (TypeConverter)Activator.CreateInstance(Type.GetType(((TypeConverterAttribute)c).ConverterTypeName))
  8200. where converter.CanConvertFrom(typeof(string))
  8201. && converter.CanConvertTo(typeof(string))
  8202. select converter)
  8203. .FirstOrDefault();
  8204. }
  8205. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  8206. {
  8207. var converter = GetConverter(value.GetType());
  8208. var text = converter.ConvertToInvariantString(value);
  8209. writer.WriteValue(text);
  8210. }
  8211. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  8212. {
  8213. var converter = GetConverter(objectType);
  8214. return converter.ConvertFromInvariantString(reader.Value.ToString());
  8215. }
  8216. public override bool CanConvert(Type objectType)
  8217. {
  8218. return GetConverter(objectType) != null;
  8219. }
  8220. }
  8221. [Test]
  8222. public void TypeConverterOnInterface()
  8223. {
  8224. var consoleWriter = new ConsoleWriter();
  8225. // If dynamic type handling is enabled, case 1 and 3 work fine
  8226. var options = new JsonSerializerSettings
  8227. {
  8228. Converters = new JsonConverterCollection { new TypeConverterJsonConverter() },
  8229. //TypeNameHandling = TypeNameHandling.All
  8230. };
  8231. //
  8232. // Case 1: Serialize the concrete value and restore it from the interface
  8233. // Therefore we need dynamic handling of type information if the type is not serialized with the type converter directly
  8234. //
  8235. var text1 = JsonConvert.SerializeObject(consoleWriter, Formatting.Indented, options);
  8236. Assert.AreEqual(@"""Console Writer""", text1);
  8237. var restoredWriter = JsonConvert.DeserializeObject<IMyInterface>(text1, options);
  8238. Assert.AreEqual("ConsoleWriter", restoredWriter.PrintTest());
  8239. //
  8240. // Case 2: Serialize a dictionary where the interface is the key
  8241. // The key is always serialized with its ToString() method and therefore needs a mechanism to be restored from that (using the type converter)
  8242. //
  8243. var dict2 = new Dictionary<IMyInterface, string>();
  8244. dict2.Add(consoleWriter, "Console");
  8245. var text2 = JsonConvert.SerializeObject(dict2, Formatting.Indented, options);
  8246. Assert.AreEqual(@"{
  8247. ""Console Writer"": ""Console""
  8248. }", text2);
  8249. var restoredObject = JsonConvert.DeserializeObject<Dictionary<IMyInterface, string>>(text2, options);
  8250. Assert.AreEqual("ConsoleWriter", restoredObject.First().Key.PrintTest());
  8251. //
  8252. // Case 3 Serialize a dictionary where the interface is the value
  8253. // The key is always serialized with its ToString() method and therefore needs a mechanism to be restored from that (using the type converter)
  8254. //
  8255. var dict3 = new Dictionary<string, IMyInterface>();
  8256. dict3.Add("Console", consoleWriter);
  8257. var text3 = JsonConvert.SerializeObject(dict3, Formatting.Indented, options);
  8258. Assert.AreEqual(@"{
  8259. ""Console"": ""Console Writer""
  8260. }", text3);
  8261. var restoredDict2 = JsonConvert.DeserializeObject<Dictionary<string, IMyInterface>>(text3, options);
  8262. Assert.AreEqual("ConsoleWriter", restoredDict2.First().Value.PrintTest());
  8263. }
  8264. #endif
  8265. [Test]
  8266. public void Main()
  8267. {
  8268. ParticipantEntity product = new ParticipantEntity();
  8269. product.Properties = new Dictionary<string, string> { { "s", "d" } };
  8270. string json = JsonConvert.SerializeObject(product);
  8271. Console.WriteLine(json);
  8272. ParticipantEntity deserializedProduct = JsonConvert.DeserializeObject<ParticipantEntity>(json);
  8273. }
  8274. internal class ParticipantEntity
  8275. {
  8276. private Dictionary<string, string> _properties;
  8277. [JsonConstructor]
  8278. public ParticipantEntity()
  8279. {
  8280. }
  8281. /// <summary>
  8282. /// Gets or sets the date and time that the participant was created in the CU.
  8283. /// </summary>
  8284. [JsonProperty(PropertyName = "pa_created", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)]
  8285. public DateTimeOffset CreationDate { get; internal set; }
  8286. /// <summary>
  8287. /// Gets the properties of the participant.
  8288. /// </summary>
  8289. [JsonProperty(PropertyName = "pa_info")]
  8290. public Dictionary<string, string> Properties
  8291. {
  8292. get { return _properties ?? (_properties = new Dictionary<string, string>()); }
  8293. set { _properties = value; }
  8294. }
  8295. }
  8296. #if !(PORTABLE || NETFX_CORE)
  8297. public class ConvertibleId : IConvertible
  8298. {
  8299. public int Value;
  8300. TypeCode IConvertible.GetTypeCode()
  8301. {
  8302. return TypeCode.Object;
  8303. }
  8304. object IConvertible.ToType(Type conversionType, IFormatProvider provider)
  8305. {
  8306. if (conversionType == typeof(object))
  8307. {
  8308. return this;
  8309. }
  8310. if (conversionType == typeof(int))
  8311. {
  8312. return (int)Value;
  8313. }
  8314. if (conversionType == typeof(long))
  8315. {
  8316. return (long)Value;
  8317. }
  8318. if (conversionType == typeof(string))
  8319. {
  8320. return Value.ToString(CultureInfo.InvariantCulture);
  8321. }
  8322. throw new InvalidCastException();
  8323. }
  8324. bool IConvertible.ToBoolean(IFormatProvider provider)
  8325. {
  8326. throw new InvalidCastException();
  8327. }
  8328. byte IConvertible.ToByte(IFormatProvider provider)
  8329. {
  8330. throw new InvalidCastException();
  8331. }
  8332. char IConvertible.ToChar(IFormatProvider provider)
  8333. {
  8334. throw new InvalidCastException();
  8335. }
  8336. DateTime IConvertible.ToDateTime(IFormatProvider provider)
  8337. {
  8338. throw new InvalidCastException();
  8339. }
  8340. decimal IConvertible.ToDecimal(IFormatProvider provider)
  8341. {
  8342. throw new InvalidCastException();
  8343. }
  8344. double IConvertible.ToDouble(IFormatProvider provider)
  8345. {
  8346. throw new InvalidCastException();
  8347. }
  8348. short IConvertible.ToInt16(IFormatProvider provider)
  8349. {
  8350. return (short)Value;
  8351. }
  8352. int IConvertible.ToInt32(IFormatProvider provider)
  8353. {
  8354. return Value;
  8355. }
  8356. long IConvertible.ToInt64(IFormatProvider provider)
  8357. {
  8358. return (long)Value;
  8359. }
  8360. sbyte IConvertible.ToSByte(IFormatProvider provider)
  8361. {
  8362. throw new InvalidCastException();
  8363. }
  8364. float IConvertible.ToSingle(IFormatProvider provider)
  8365. {
  8366. throw new InvalidCastException();
  8367. }
  8368. string IConvertible.ToString(IFormatProvider provider)
  8369. {
  8370. throw new InvalidCastException();
  8371. }
  8372. ushort IConvertible.ToUInt16(IFormatProvider provider)
  8373. {
  8374. throw new InvalidCastException();
  8375. }
  8376. uint IConvertible.ToUInt32(IFormatProvider provider)
  8377. {
  8378. throw new InvalidCastException();
  8379. }
  8380. ulong IConvertible.ToUInt64(IFormatProvider provider)
  8381. {
  8382. throw new InvalidCastException();
  8383. }
  8384. }
  8385. public class TestClassConvertable
  8386. {
  8387. public ConvertibleId Id;
  8388. public int X;
  8389. }
  8390. [Test]
  8391. public void ConvertibleIdTest()
  8392. {
  8393. var c = new TestClassConvertable { Id = new ConvertibleId { Value = 1 }, X = 2 };
  8394. var s = JsonConvert.SerializeObject(c, Formatting.Indented);
  8395. Assert.AreEqual(@"{
  8396. ""Id"": ""1"",
  8397. ""X"": 2
  8398. }", s);
  8399. }
  8400. #endif
  8401. [Test]
  8402. public void RoundtripUriOriginalString()
  8403. {
  8404. string originalUri = "https://test.com?m=a%2bb";
  8405. Uri uriWithPlus = new Uri(originalUri);
  8406. string jsonWithPlus = JsonConvert.SerializeObject(uriWithPlus);
  8407. Uri uriWithPlus2 = JsonConvert.DeserializeObject<Uri>(jsonWithPlus);
  8408. Assert.AreEqual(originalUri, uriWithPlus2.OriginalString);
  8409. }
  8410. }
  8411. public class PersonReference
  8412. {
  8413. internal Guid Id { get; set; }
  8414. public string Name { get; set; }
  8415. public PersonReference Spouse { get; set; }
  8416. }
  8417. public enum Antworten
  8418. {
  8419. First,
  8420. Second
  8421. }
  8422. public class SelectListItem
  8423. {
  8424. public string Text { get; set; }
  8425. public string Value { get; set; }
  8426. public bool Selected { get; set; }
  8427. }
  8428. #if !(NETFX_CORE || PORTABLE)
  8429. [Serializable]
  8430. public class AnswerFilterModel
  8431. {
  8432. [NonSerialized]
  8433. private readonly IList answerValues;
  8434. /// <summary>
  8435. /// Initializes a new instance of the class.
  8436. /// </summary>
  8437. public AnswerFilterModel()
  8438. {
  8439. answerValues = (from answer in Enum.GetNames(typeof(Antworten))
  8440. select new SelectListItem { Text = answer, Value = answer, Selected = false })
  8441. .ToList();
  8442. }
  8443. /// <summary>
  8444. /// Gets or sets a value indicating whether active.
  8445. /// </summary>
  8446. public bool Active { get; set; }
  8447. /// <summary>
  8448. /// Gets or sets a value indicating whether ja.
  8449. /// nach bisherigen Antworten.
  8450. /// </summary>
  8451. public bool Ja { get; set; }
  8452. /// <summary>
  8453. /// Gets or sets a value indicating whether handlungsbedarf.
  8454. /// </summary>
  8455. public bool Handlungsbedarf { get; set; }
  8456. /// <summary>
  8457. /// Gets or sets a value indicating whether beratungsbedarf.
  8458. /// </summary>
  8459. public bool Beratungsbedarf { get; set; }
  8460. /// <summary>
  8461. /// Gets or sets a value indicating whether unzutreffend.
  8462. /// </summary>
  8463. public bool Unzutreffend { get; set; }
  8464. /// <summary>
  8465. /// Gets or sets a value indicating whether unbeantwortet.
  8466. /// </summary>
  8467. public bool Unbeantwortet { get; set; }
  8468. /// <summary>
  8469. /// Gets the answer values.
  8470. /// </summary>
  8471. public IEnumerable AnswerValues
  8472. {
  8473. get { return answerValues; }
  8474. }
  8475. }
  8476. [Serializable]
  8477. public class PersonSerializable
  8478. {
  8479. public PersonSerializable()
  8480. {
  8481. }
  8482. private string _name = "";
  8483. public string Name
  8484. {
  8485. get { return _name; }
  8486. set { _name = value; }
  8487. }
  8488. [NonSerialized]
  8489. private int _age = 0;
  8490. public int Age
  8491. {
  8492. get { return _age; }
  8493. set { _age = value; }
  8494. }
  8495. }
  8496. #endif
  8497. public class Event
  8498. {
  8499. public string EventName { get; set; }
  8500. public string Venue { get; set; }
  8501. [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))]
  8502. public IList<DateTime> Performances { get; set; }
  8503. }
  8504. public class PropertyItemConverter
  8505. {
  8506. [JsonProperty(ItemConverterType = typeof(MetroStringConverter))]
  8507. public IList<string> Data { get; set; }
  8508. }
  8509. public class PersonWithPrivateConstructor
  8510. {
  8511. private PersonWithPrivateConstructor()
  8512. {
  8513. }
  8514. public static PersonWithPrivateConstructor CreatePerson()
  8515. {
  8516. return new PersonWithPrivateConstructor();
  8517. }
  8518. public string Name { get; set; }
  8519. public int Age { get; set; }
  8520. }
  8521. public class DateTimeWrapper
  8522. {
  8523. public DateTime Value { get; set; }
  8524. }
  8525. public class Widget1
  8526. {
  8527. public WidgetId1? Id { get; set; }
  8528. }
  8529. [JsonConverter(typeof(WidgetIdJsonConverter))]
  8530. public struct WidgetId1
  8531. {
  8532. public long Value { get; set; }
  8533. }
  8534. public class WidgetIdJsonConverter : JsonConverter
  8535. {
  8536. public override bool CanConvert(Type objectType)
  8537. {
  8538. return objectType == typeof(WidgetId1) || objectType == typeof(WidgetId1?);
  8539. }
  8540. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  8541. {
  8542. WidgetId1 id = (WidgetId1)value;
  8543. writer.WriteValue(id.Value.ToString());
  8544. }
  8545. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  8546. {
  8547. if (reader.TokenType == JsonToken.Null)
  8548. return null;
  8549. return new WidgetId1 { Value = int.Parse(reader.Value.ToString()) };
  8550. }
  8551. }
  8552. public enum MyEnum
  8553. {
  8554. Value1,
  8555. Value2,
  8556. Value3
  8557. }
  8558. public class WithEnums
  8559. {
  8560. public int Id { get; set; }
  8561. public MyEnum? NullableEnum { get; set; }
  8562. }
  8563. public class Item
  8564. {
  8565. public Guid SourceTypeID { get; set; }
  8566. public Guid BrokerID { get; set; }
  8567. public double Latitude { get; set; }
  8568. public double Longitude { get; set; }
  8569. public DateTime TimeStamp { get; set; }
  8570. [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
  8571. public object Payload { get; set; }
  8572. }
  8573. public class NullableGuid
  8574. {
  8575. public Guid? Id { get; set; }
  8576. }
  8577. public class Widget
  8578. {
  8579. public WidgetId? Id { get; set; }
  8580. }
  8581. public struct WidgetId
  8582. {
  8583. public string Value { get; set; }
  8584. }
  8585. public class DecimalTestClass
  8586. {
  8587. public decimal Quantity { get; set; }
  8588. public double OptionalQuantity { get; set; }
  8589. }
  8590. public class TestObject
  8591. {
  8592. public TestObject()
  8593. {
  8594. }
  8595. public TestObject(string name, byte[] data)
  8596. {
  8597. Name = name;
  8598. Data = data;
  8599. }
  8600. public string Name { get; set; }
  8601. public byte[] Data { get; set; }
  8602. }
  8603. public class UriGuidTimeSpanTestClass
  8604. {
  8605. public Guid Guid { get; set; }
  8606. public Guid? NullableGuid { get; set; }
  8607. public TimeSpan TimeSpan { get; set; }
  8608. public TimeSpan? NullableTimeSpan { get; set; }
  8609. public Uri Uri { get; set; }
  8610. }
  8611. internal class Aa
  8612. {
  8613. public int no;
  8614. }
  8615. internal class Bb : Aa
  8616. {
  8617. public new bool no;
  8618. }
  8619. #if !(NET35 || NET20)
  8620. [JsonObject(MemberSerialization.OptIn)]
  8621. public class GameObject
  8622. {
  8623. [JsonProperty]
  8624. public string Id { get; set; }
  8625. [JsonProperty]
  8626. public string Name { get; set; }
  8627. [JsonProperty]
  8628. public ConcurrentDictionary<string, Component> Components;
  8629. public GameObject()
  8630. {
  8631. Components = new ConcurrentDictionary<string, Component>();
  8632. }
  8633. }
  8634. [JsonObject(MemberSerialization.OptIn)]
  8635. public class Component
  8636. {
  8637. [JsonIgnore] // Ignore circular reference
  8638. public GameObject GameObject { get; set; }
  8639. public Component()
  8640. {
  8641. }
  8642. }
  8643. [JsonObject(MemberSerialization.OptIn)]
  8644. public class TestComponent : Component
  8645. {
  8646. [JsonProperty]
  8647. public int MyProperty { get; set; }
  8648. public TestComponent()
  8649. {
  8650. }
  8651. }
  8652. #endif
  8653. [JsonObject(MemberSerialization.OptIn)]
  8654. public class TestComponentSimple
  8655. {
  8656. [JsonProperty]
  8657. public int MyProperty { get; set; }
  8658. public TestComponentSimple()
  8659. {
  8660. }
  8661. }
  8662. [JsonObject(ItemRequired = Required.Always)]
  8663. public class RequiredObject
  8664. {
  8665. public int? NonAttributeProperty { get; set; }
  8666. [JsonProperty]
  8667. public int? UnsetProperty { get; set; }
  8668. [JsonProperty(Required = Required.Default)]
  8669. public int? DefaultProperty { get; set; }
  8670. [JsonProperty(Required = Required.AllowNull)]
  8671. public int? AllowNullProperty { get; set; }
  8672. [JsonProperty(Required = Required.Always)]
  8673. public int? AlwaysProperty { get; set; }
  8674. }
  8675. public class MetroStringConverter : JsonConverter
  8676. {
  8677. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  8678. {
  8679. #if !(NETFX_CORE)
  8680. writer.WriteValue(":::" + value.ToString().ToUpper(CultureInfo.InvariantCulture) + ":::");
  8681. #else
  8682. writer.WriteValue(":::" + value.ToString().ToUpper() + ":::");
  8683. #endif
  8684. }
  8685. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  8686. {
  8687. string s = (string)reader.Value;
  8688. if (s == null)
  8689. return null;
  8690. #if !(NETFX_CORE)
  8691. return s.ToLower(CultureInfo.InvariantCulture).Trim(new[] { ':' });
  8692. #else
  8693. return s.ToLower().Trim(new[] { ':' });
  8694. #endif
  8695. }
  8696. public override bool CanConvert(Type objectType)
  8697. {
  8698. return objectType == typeof(string);
  8699. }
  8700. }
  8701. public class MetroPropertyNameResolver : DefaultContractResolver
  8702. {
  8703. protected internal override string ResolvePropertyName(string propertyName)
  8704. {
  8705. #if !(NETFX_CORE)
  8706. return ":::" + propertyName.ToUpper(CultureInfo.InvariantCulture) + ":::";
  8707. #else
  8708. return ":::" + propertyName.ToUpper() + ":::";
  8709. #endif
  8710. }
  8711. }
  8712. #if !(NET20 || NET35)
  8713. [DataContract]
  8714. public class DataContractSerializationAttributesClass
  8715. {
  8716. public string NoAttribute { get; set; }
  8717. [IgnoreDataMember]
  8718. public string IgnoreDataMemberAttribute { get; set; }
  8719. [DataMember]
  8720. public string DataMemberAttribute { get; set; }
  8721. [IgnoreDataMember]
  8722. [DataMember]
  8723. public string IgnoreDataMemberAndDataMemberAttribute { get; set; }
  8724. }
  8725. public class PocoDataContractSerializationAttributesClass
  8726. {
  8727. public string NoAttribute { get; set; }
  8728. [IgnoreDataMember]
  8729. public string IgnoreDataMemberAttribute { get; set; }
  8730. [DataMember]
  8731. public string DataMemberAttribute { get; set; }
  8732. [IgnoreDataMember]
  8733. [DataMember]
  8734. public string IgnoreDataMemberAndDataMemberAttribute { get; set; }
  8735. }
  8736. #endif
  8737. public class Array2D
  8738. {
  8739. public string Before { get; set; }
  8740. public int[,] Coordinates { get; set; }
  8741. public string After { get; set; }
  8742. }
  8743. public class Array3D
  8744. {
  8745. public string Before { get; set; }
  8746. public int[,,] Coordinates { get; set; }
  8747. public string After { get; set; }
  8748. }
  8749. public class Array3DWithConverter
  8750. {
  8751. public string Before { get; set; }
  8752. [JsonProperty(ItemConverterType = typeof(IntToFloatConverter))]
  8753. public int[,,] Coordinates { get; set; }
  8754. public string After { get; set; }
  8755. }
  8756. public class IntToFloatConverter : JsonConverter
  8757. {
  8758. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  8759. {
  8760. writer.WriteValue(Convert.ToDouble(value));
  8761. }
  8762. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  8763. {
  8764. return Convert.ToInt32(reader.Value);
  8765. }
  8766. public override bool CanConvert(Type objectType)
  8767. {
  8768. return objectType == typeof(int);
  8769. }
  8770. }
  8771. public class ShouldSerializeTestClass
  8772. {
  8773. internal bool _shouldSerializeName;
  8774. public string Name { get; set; }
  8775. public int Age { get; set; }
  8776. public void ShouldSerializeAge()
  8777. {
  8778. // dummy. should never be used because it doesn't return bool
  8779. }
  8780. public bool ShouldSerializeName()
  8781. {
  8782. return _shouldSerializeName;
  8783. }
  8784. }
  8785. public class SpecifiedTestClass
  8786. {
  8787. private bool _nameSpecified;
  8788. public string Name { get; set; }
  8789. public int Age { get; set; }
  8790. public int Weight { get; set; }
  8791. public int Height { get; set; }
  8792. public int FavoriteNumber { get; set; }
  8793. // dummy. should never be used because it isn't of type bool
  8794. [JsonIgnore]
  8795. public long AgeSpecified { get; set; }
  8796. [JsonIgnore]
  8797. public bool NameSpecified
  8798. {
  8799. get { return _nameSpecified; }
  8800. set { _nameSpecified = value; }
  8801. }
  8802. [JsonIgnore]
  8803. public bool WeightSpecified;
  8804. [JsonIgnore]
  8805. [System.Xml.Serialization.XmlIgnoreAttribute]
  8806. public bool HeightSpecified;
  8807. [JsonIgnore]
  8808. public bool FavoriteNumberSpecified
  8809. {
  8810. // get only example
  8811. get { return FavoriteNumber != 0; }
  8812. }
  8813. }
  8814. public class DirectoryAccount
  8815. {
  8816. // normal deserialization
  8817. public string DisplayName { get; set; }
  8818. // these properties are set in OnDeserialized
  8819. public string UserName { get; set; }
  8820. public string Domain { get; set; }
  8821. [JsonExtensionData]
  8822. private IDictionary<string, JToken> _additionalData;
  8823. [OnDeserialized]
  8824. private void OnDeserialized(StreamingContext context)
  8825. {
  8826. // SAMAccountName is not deserialized to any property
  8827. // and so it is added to the extension data dictionary
  8828. string samAccountName = (string)_additionalData["SAMAccountName"];
  8829. Domain = samAccountName.Split('\\')[0];
  8830. UserName = samAccountName.Split('\\')[1];
  8831. }
  8832. public DirectoryAccount()
  8833. {
  8834. _additionalData = new Dictionary<string, JToken>();
  8835. }
  8836. }
  8837. #if !NETFX_CORE
  8838. public struct Ratio : IConvertible, IFormattable, ISerializable
  8839. {
  8840. private readonly int _numerator;
  8841. private readonly int _denominator;
  8842. public Ratio(int numerator, int denominator)
  8843. {
  8844. _numerator = numerator;
  8845. _denominator = denominator;
  8846. }
  8847. #region Properties
  8848. public int Numerator
  8849. {
  8850. get { return _numerator; }
  8851. }
  8852. public int Denominator
  8853. {
  8854. get { return _denominator; }
  8855. }
  8856. public bool IsNan
  8857. {
  8858. get { return _denominator == 0; }
  8859. }
  8860. #endregion
  8861. #region Serialization operations
  8862. public Ratio(SerializationInfo info, StreamingContext context)
  8863. {
  8864. _numerator = info.GetInt32("n");
  8865. _denominator = info.GetInt32("d");
  8866. }
  8867. public void GetObjectData(SerializationInfo info, StreamingContext context)
  8868. {
  8869. info.AddValue("n", _numerator);
  8870. info.AddValue("d", _denominator);
  8871. }
  8872. #endregion
  8873. #region IConvertible Members
  8874. public TypeCode GetTypeCode()
  8875. {
  8876. return TypeCode.Object;
  8877. }
  8878. public bool ToBoolean(IFormatProvider provider)
  8879. {
  8880. return _numerator == 0;
  8881. }
  8882. public byte ToByte(IFormatProvider provider)
  8883. {
  8884. return (byte)(_numerator / _denominator);
  8885. }
  8886. public char ToChar(IFormatProvider provider)
  8887. {
  8888. return Convert.ToChar(_numerator / _denominator);
  8889. }
  8890. public DateTime ToDateTime(IFormatProvider provider)
  8891. {
  8892. return Convert.ToDateTime(_numerator / _denominator);
  8893. }
  8894. public decimal ToDecimal(IFormatProvider provider)
  8895. {
  8896. return (decimal)_numerator / _denominator;
  8897. }
  8898. public double ToDouble(IFormatProvider provider)
  8899. {
  8900. return _denominator == 0
  8901. ? double.NaN
  8902. : (double)_numerator / _denominator;
  8903. }
  8904. public short ToInt16(IFormatProvider provider)
  8905. {
  8906. return (short)(_numerator / _denominator);
  8907. }
  8908. public int ToInt32(IFormatProvider provider)
  8909. {
  8910. return _numerator / _denominator;
  8911. }
  8912. public long ToInt64(IFormatProvider provider)
  8913. {
  8914. return _numerator / _denominator;
  8915. }
  8916. public sbyte ToSByte(IFormatProvider provider)
  8917. {
  8918. return (sbyte)(_numerator / _denominator);
  8919. }
  8920. public float ToSingle(IFormatProvider provider)
  8921. {
  8922. return _denominator == 0
  8923. ? float.NaN
  8924. : (float)_numerator / _denominator;
  8925. }
  8926. public string ToString(IFormatProvider provider)
  8927. {
  8928. return _denominator == 1
  8929. ? _numerator.ToString(provider)
  8930. : _numerator.ToString(provider) + "/" + _denominator.ToString(provider);
  8931. }
  8932. public object ToType(Type conversionType, IFormatProvider provider)
  8933. {
  8934. return Convert.ChangeType(ToDouble(provider), conversionType, provider);
  8935. }
  8936. public ushort ToUInt16(IFormatProvider provider)
  8937. {
  8938. return (ushort)(_numerator / _denominator);
  8939. }
  8940. public uint ToUInt32(IFormatProvider provider)
  8941. {
  8942. return (uint)(_numerator / _denominator);
  8943. }
  8944. public ulong ToUInt64(IFormatProvider provider)
  8945. {
  8946. return (ulong)(_numerator / _denominator);
  8947. }
  8948. #endregion
  8949. #region String operations
  8950. public override string ToString()
  8951. {
  8952. return ToString(CultureInfo.InvariantCulture);
  8953. }
  8954. public string ToString(string format, IFormatProvider formatProvider)
  8955. {
  8956. return ToString(CultureInfo.InvariantCulture);
  8957. }
  8958. public static Ratio Parse(string input)
  8959. {
  8960. return Parse(input, CultureInfo.InvariantCulture);
  8961. }
  8962. public static Ratio Parse(string input, IFormatProvider formatProvider)
  8963. {
  8964. Ratio result;
  8965. if (!TryParse(input, formatProvider, out result))
  8966. {
  8967. throw new FormatException(
  8968. string.Format(
  8969. CultureInfo.InvariantCulture,
  8970. "Text '{0}' is invalid text representation of ratio",
  8971. input));
  8972. }
  8973. return result;
  8974. }
  8975. public static bool TryParse(string input, out Ratio result)
  8976. {
  8977. return TryParse(input, CultureInfo.InvariantCulture, out result);
  8978. }
  8979. public static bool TryParse(string input, IFormatProvider formatProvider, out Ratio result)
  8980. {
  8981. if (input != null)
  8982. {
  8983. var fractionIndex = input.IndexOf('/');
  8984. int numerator;
  8985. if (fractionIndex < 0)
  8986. {
  8987. if (int.TryParse(input, NumberStyles.Integer, formatProvider, out numerator))
  8988. {
  8989. result = new Ratio(numerator, 1);
  8990. return true;
  8991. }
  8992. }
  8993. else
  8994. {
  8995. int denominator;
  8996. if (int.TryParse(input.Substring(0, fractionIndex), NumberStyles.Integer, formatProvider, out numerator) &&
  8997. int.TryParse(input.Substring(fractionIndex + 1), NumberStyles.Integer, formatProvider, out denominator))
  8998. {
  8999. result = new Ratio(numerator, denominator);
  9000. return true;
  9001. }
  9002. }
  9003. }
  9004. result = default(Ratio);
  9005. return false;
  9006. }
  9007. #endregion
  9008. }
  9009. #endif
  9010. }