PageRenderTime 91ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/desktop_clients/Visual Studio/Crear beneficiarios/Json100r3/Source/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs

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