PageRenderTime 56ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 1ms

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

http://github.com/ayende/ravendb
C# | 9246 lines | 8176 code | 958 blank | 112 comment | 101 complexity | 80400fc04ff1db65c375fbcba080b06e MD5 | raw file
Possible License(s): GPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, Apache-2.0, BSD-3-Clause, CC-BY-SA-3.0

Large files files are truncated, but you can click here to view the full file

  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. using System;
  26. using System.ComponentModel;
  27. #if !(NET35 || NET20)
  28. using System.Collections.Concurrent;
  29. #endif
  30. using System.Collections.Generic;
  31. #if !(NET20 || NET35 || PORTABLE || DNXCORE50)
  32. using System.Numerics;
  33. #endif
  34. #if !(NET20 || NETFX_CORE || 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 NETFX_CORE
  45. using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  46. using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  47. using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  48. #elif DNXCORE50
  49. using Xunit;
  50. using Test = Xunit.FactAttribute;
  51. using Assert = Newtonsoft.Json.Tests.XUnitAssert;
  52. #else
  53. using NUnit.Framework;
  54. #endif
  55. using Newtonsoft.Json;
  56. using System.IO;
  57. using System.Collections;
  58. using System.Xml;
  59. using System.Xml.Serialization;
  60. using System.Collections.ObjectModel;
  61. using Newtonsoft.Json.Bson;
  62. using Newtonsoft.Json.Linq;
  63. using Newtonsoft.Json.Converters;
  64. #if !NET20
  65. using System.Runtime.Serialization.Json;
  66. #endif
  67. using Newtonsoft.Json.Serialization;
  68. using Newtonsoft.Json.Tests.Linq;
  69. using Newtonsoft.Json.Tests.TestObjects;
  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. #else
  85. using System.Linq;
  86. #endif
  87. #if !(NETFX_CORE || DNXCORE50)
  88. using System.Drawing;
  89. using System.Diagnostics;
  90. #endif
  91. namespace Newtonsoft.Json.Tests.Serialization
  92. {
  93. [TestFixture]
  94. public class JsonSerializerTest : TestFixtureBase
  95. {
  96. public class DictionaryKeyContractResolver : DefaultContractResolver
  97. {
  98. protected override string ResolveDictionaryKey(string dictionaryKey)
  99. {
  100. return dictionaryKey;
  101. }
  102. protected override string ResolvePropertyName(string propertyName)
  103. {
  104. return propertyName.ToUpper(CultureInfo.InvariantCulture);
  105. }
  106. }
  107. [Test]
  108. public void DictionaryKeyContractResolverTest()
  109. {
  110. var person = new
  111. {
  112. Name = "James",
  113. Age = 1,
  114. RoleNames = new Dictionary<string, bool>
  115. {
  116. { "IsAdmin", true },
  117. { "IsModerator", false }
  118. }
  119. };
  120. string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings
  121. {
  122. ContractResolver = new DictionaryKeyContractResolver()
  123. });
  124. Assert.AreEqual(@"{
  125. ""NAME"": ""James"",
  126. ""AGE"": 1,
  127. ""ROLENAMES"": {
  128. ""IsAdmin"": true,
  129. ""IsModerator"": false
  130. }
  131. }", json);
  132. }
  133. [Test]
  134. public void IncompleteContainers()
  135. {
  136. ExceptionAssert.Throws<JsonSerializationException>(
  137. () => JsonConvert.DeserializeObject<IList<int>>("[1,"),
  138. "Unexpected end when deserializing array. Path '[0]', line 1, position 3.");
  139. ExceptionAssert.Throws<JsonSerializationException>(
  140. () => JsonConvert.DeserializeObject<IList<int>>("[1"),
  141. "Unexpected end when deserializing array. Path '[0]', line 1, position 2.");
  142. ExceptionAssert.Throws<JsonSerializationException>(
  143. () => JsonConvert.DeserializeObject<IDictionary<string, int>>("{'key':1,"),
  144. "Unexpected end when deserializing object. Path 'key', line 1, position 9.");
  145. ExceptionAssert.Throws<JsonSerializationException>(
  146. () => JsonConvert.DeserializeObject<IDictionary<string, int>>("{'key':1"),
  147. "Unexpected end when deserializing object. Path 'key', line 1, position 8.");
  148. ExceptionAssert.Throws<JsonSerializationException>(
  149. () => JsonConvert.DeserializeObject<IncompleteTestClass>("{'key':1,"),
  150. "Unexpected end when deserializing object. Path 'key', line 1, position 9.");
  151. ExceptionAssert.Throws<JsonSerializationException>(
  152. () => JsonConvert.DeserializeObject<IncompleteTestClass>("{'key':1"),
  153. "Unexpected end when deserializing object. Path 'key', line 1, position 8.");
  154. }
  155. public class IncompleteTestClass
  156. {
  157. public int Key { get; set; }
  158. }
  159. #if !NET20
  160. public enum EnumA
  161. {
  162. [EnumMember(Value = "value_a")]
  163. ValueA
  164. }
  165. [Test]
  166. public void DeserializeEnumsByName()
  167. {
  168. var e1 = JsonConvert.DeserializeObject<EnumA>("'ValueA'");
  169. Assert.AreEqual(EnumA.ValueA, e1);
  170. var e2 = JsonConvert.DeserializeObject<EnumA>("'value_a'", new StringEnumConverter());
  171. Assert.AreEqual(EnumA.ValueA, e2);
  172. }
  173. #endif
  174. public class RequiredPropertyTestClass
  175. {
  176. [JsonRequired]
  177. internal string Name { get; set; }
  178. }
  179. [Test]
  180. public void RequiredPropertyTest()
  181. {
  182. RequiredPropertyTestClass c1 = new RequiredPropertyTestClass();
  183. ExceptionAssert.Throws<JsonSerializationException>(
  184. () => JsonConvert.SerializeObject(c1),
  185. "Cannot write a null value for property 'Name'. Property requires a value. Path ''.");
  186. RequiredPropertyTestClass c2 = new RequiredPropertyTestClass
  187. {
  188. Name = "Name!"
  189. };
  190. string json = JsonConvert.SerializeObject(c2);
  191. Assert.AreEqual(@"{""Name"":""Name!""}", json);
  192. ExceptionAssert.Throws<JsonSerializationException>(
  193. () => JsonConvert.DeserializeObject<RequiredPropertyTestClass>(@"{}"),
  194. "Required property 'Name' not found in JSON. Path '', line 1, position 2.");
  195. ExceptionAssert.Throws<JsonSerializationException>(
  196. () => JsonConvert.DeserializeObject<RequiredPropertyTestClass>(@"{""Name"":null}"),
  197. "Required property 'Name' expects a value but got null. Path '', line 1, position 13.");
  198. RequiredPropertyTestClass c3 = JsonConvert.DeserializeObject<RequiredPropertyTestClass>(@"{""Name"":""Name!""}");
  199. Assert.AreEqual("Name!", c3.Name);
  200. }
  201. public class RequiredPropertyConstructorTestClass
  202. {
  203. public RequiredPropertyConstructorTestClass(string name)
  204. {
  205. Name = name;
  206. }
  207. [JsonRequired]
  208. internal string Name { get; set; }
  209. }
  210. [Test]
  211. public void RequiredPropertyConstructorTest()
  212. {
  213. RequiredPropertyConstructorTestClass c1 = new RequiredPropertyConstructorTestClass(null);
  214. ExceptionAssert.Throws<JsonSerializationException>(
  215. () => JsonConvert.SerializeObject(c1),
  216. "Cannot write a null value for property 'Name'. Property requires a value. Path ''.");
  217. RequiredPropertyConstructorTestClass c2 = new RequiredPropertyConstructorTestClass("Name!");
  218. string json = JsonConvert.SerializeObject(c2);
  219. Assert.AreEqual(@"{""Name"":""Name!""}", json);
  220. ExceptionAssert.Throws<JsonSerializationException>(
  221. () => JsonConvert.DeserializeObject<RequiredPropertyConstructorTestClass>(@"{}"),
  222. "Required property 'Name' not found in JSON. Path '', line 1, position 2.");
  223. RequiredPropertyConstructorTestClass c3 = JsonConvert.DeserializeObject<RequiredPropertyConstructorTestClass>(@"{""Name"":""Name!""}");
  224. Assert.AreEqual("Name!", c3.Name);
  225. }
  226. public class IgnoredPropertiesTestClass
  227. {
  228. [JsonIgnore]
  229. public Version IgnoredProperty { get; set; }
  230. [JsonIgnore]
  231. public List<Version> IgnoredList { get; set; }
  232. [JsonIgnore]
  233. public Dictionary<string, Version> IgnoredDictionary { get; set; }
  234. [JsonProperty(Required = Required.Always)]
  235. public string Name { get; set; }
  236. }
  237. public class IgnoredPropertiesContractResolver : DefaultContractResolver
  238. {
  239. public override JsonContract ResolveContract(Type type)
  240. {
  241. if (type == typeof(Version))
  242. throw new Exception("Error!");
  243. return base.ResolveContract(type);
  244. }
  245. }
  246. [Test]
  247. public void NeverResolveIgnoredPropertyTypes()
  248. {
  249. Version v = new Version(1, 2, 3, 4);
  250. IgnoredPropertiesTestClass c1 = new IgnoredPropertiesTestClass
  251. {
  252. IgnoredProperty = v,
  253. IgnoredList = new List<Version>
  254. {
  255. v
  256. },
  257. IgnoredDictionary = new Dictionary<string, Version>
  258. {
  259. { "Value", v }
  260. },
  261. Name = "Name!"
  262. };
  263. string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings
  264. {
  265. ContractResolver = new IgnoredPropertiesContractResolver()
  266. });
  267. Assert.AreEqual(@"{
  268. ""Name"": ""Name!""
  269. }", json);
  270. string deserializeJson = @"{
  271. ""IgnoredList"": [
  272. {
  273. ""Major"": 1,
  274. ""Minor"": 2,
  275. ""Build"": 3,
  276. ""Revision"": 4,
  277. ""MajorRevision"": 0,
  278. ""MinorRevision"": 4
  279. }
  280. ],
  281. ""IgnoredDictionary"": {
  282. ""Value"": {
  283. ""Major"": 1,
  284. ""Minor"": 2,
  285. ""Build"": 3,
  286. ""Revision"": 4,
  287. ""MajorRevision"": 0,
  288. ""MinorRevision"": 4
  289. }
  290. },
  291. ""Name"": ""Name!""
  292. }";
  293. IgnoredPropertiesTestClass c2 = JsonConvert.DeserializeObject<IgnoredPropertiesTestClass>(deserializeJson, new JsonSerializerSettings
  294. {
  295. ContractResolver = new IgnoredPropertiesContractResolver()
  296. });
  297. Assert.AreEqual("Name!", c2.Name);
  298. }
  299. #if !(NETFX_CORE || DNXCORE50 || NET20)
  300. [MetadataType(typeof(CustomerValidation))]
  301. public partial class CustomerWithMetadataType
  302. {
  303. public System.Guid UpdatedBy_Id { get; set; }
  304. public class CustomerValidation
  305. {
  306. [JsonIgnore]
  307. public System.Guid UpdatedBy_Id { get; set; }
  308. }
  309. }
  310. [Test]
  311. public void SerializeMetadataType()
  312. {
  313. CustomerWithMetadataType c = new CustomerWithMetadataType();
  314. c.UpdatedBy_Id = Guid.NewGuid();
  315. string json = JsonConvert.SerializeObject(c);
  316. Assert.AreEqual("{}", json);
  317. CustomerWithMetadataType c2 = JsonConvert.DeserializeObject<CustomerWithMetadataType>("{'UpdatedBy_Id':'F6E0666D-13C7-4745-B486-800812C8F6DE'}");
  318. Assert.AreEqual(Guid.Empty, c2.UpdatedBy_Id);
  319. }
  320. [Serializable]
  321. public partial class FaqItem
  322. {
  323. public FaqItem()
  324. {
  325. this.Sections = new HashSet<FaqSection>();
  326. }
  327. public int FaqId { get; set; }
  328. public string Name { get; set; }
  329. public bool IsDeleted { get; set; }
  330. public virtual ICollection<FaqSection> Sections { get; set; }
  331. }
  332. [MetadataType(typeof(FaqItemMetadata))]
  333. partial class FaqItem
  334. {
  335. [JsonProperty("FullSectionsProp")]
  336. public ICollection<FaqSection> FullSections
  337. {
  338. get { return Sections; }
  339. }
  340. }
  341. public class FaqItemMetadata
  342. {
  343. [JsonIgnore]
  344. public virtual ICollection<FaqSection> Sections { get; set; }
  345. }
  346. public class FaqSection
  347. {
  348. }
  349. public class FaqItemProxy : FaqItem
  350. {
  351. public bool IsProxy { get; set; }
  352. public override ICollection<FaqSection> Sections
  353. {
  354. get { return base.Sections; }
  355. set { base.Sections = value; }
  356. }
  357. }
  358. [Test]
  359. public void SerializeMetadataType2()
  360. {
  361. FaqItem c = new FaqItem();
  362. c.FaqId = 1;
  363. c.Sections.Add(new FaqSection());
  364. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  365. StringAssert.AreEqual(@"{
  366. ""FaqId"": 1,
  367. ""Name"": null,
  368. ""IsDeleted"": false,
  369. ""FullSectionsProp"": [
  370. {}
  371. ]
  372. }", json);
  373. FaqItem c2 = JsonConvert.DeserializeObject<FaqItem>(json);
  374. Assert.AreEqual(1, c2.FaqId);
  375. Assert.AreEqual(1, c2.Sections.Count);
  376. }
  377. [Test]
  378. public void SerializeMetadataTypeInheritance()
  379. {
  380. FaqItemProxy c = new FaqItemProxy();
  381. c.FaqId = 1;
  382. c.Sections.Add(new FaqSection());
  383. c.IsProxy = true;
  384. string json = JsonConvert.SerializeObject(c, Formatting.Indented);
  385. StringAssert.AreEqual(@"{
  386. ""IsProxy"": true,
  387. ""FaqId"": 1,
  388. ""Name"": null,
  389. ""IsDeleted"": false,
  390. ""FullSectionsProp"": [
  391. {}
  392. ]
  393. }", json);
  394. FaqItemProxy c2 = JsonConvert.DeserializeObject<FaqItemProxy>(json);
  395. Assert.AreEqual(1, c2.FaqId);
  396. Assert.AreEqual(1, c2.Sections.Count);
  397. }
  398. #endif
  399. public class NullTestClass
  400. {
  401. public JObject Value1 { get; set; }
  402. public JValue Value2 { get; set; }
  403. public JRaw Value3 { get; set; }
  404. public JToken Value4 { get; set; }
  405. public object Value5 { get; set; }
  406. }
  407. [Test]
  408. public void DeserializeNullToJTokenProperty()
  409. {
  410. NullTestClass otc = JsonConvert.DeserializeObject<NullTestClass>(@"{
  411. ""Value1"": null,
  412. ""Value2"": null,
  413. ""Value3"": null,
  414. ""Value4"": null,
  415. ""Value5"": null
  416. }");
  417. Assert.IsNull(otc.Value1);
  418. Assert.AreEqual(JTokenType.Null, otc.Value2.Type);
  419. Assert.AreEqual(JTokenType.Raw, otc.Value3.Type);
  420. Assert.AreEqual(JTokenType.Null, otc.Value4.Type);
  421. Assert.IsNull(otc.Value5);
  422. }
  423. public class Link
  424. {
  425. /// <summary>
  426. /// The unique identifier.
  427. /// </summary>
  428. public int Id;
  429. /// <summary>
  430. /// The parent information identifier.
  431. /// </summary>
  432. public int ParentId;
  433. /// <summary>
  434. /// The child information identifier.
  435. /// </summary>
  436. public int ChildId;
  437. }
  438. #if !(NET20 || NET35 || PORTABLE40 || PORTABLE || DNXCORE50)
  439. [Test]
  440. public void ReadIntegerWithError()
  441. {
  442. string json = @"{
  443. ParentId: 1,
  444. ChildId: 333333333333333333333333333333333333333
  445. }";
  446. Link l = JsonConvert.DeserializeObject<Link>(json, new JsonSerializerSettings
  447. {
  448. Error = (s, a) => a.ErrorContext.Handled = true
  449. });
  450. Assert.AreEqual(0, l.ChildId);
  451. }
  452. #endif
  453. #if !(NET20 || NET35)
  454. [Test]
  455. public void DeserializeObservableCollection()
  456. {
  457. ObservableCollection<string> s = JsonConvert.DeserializeObject<ObservableCollection<string>>("['1','2']");
  458. Assert.AreEqual(2, s.Count);
  459. Assert.AreEqual("1", s[0]);
  460. Assert.AreEqual("2", s[1]);
  461. }
  462. #endif
  463. #if !NET20
  464. [Test]
  465. public void PopulateResetSettings()
  466. {
  467. JsonTextReader reader = new JsonTextReader(new StringReader(@"[""2000-01-01T01:01:01+00:00""]"));
  468. Assert.AreEqual(DateParseHandling.DateTime, reader.DateParseHandling);
  469. JsonSerializer serializer = new JsonSerializer();
  470. serializer.DateParseHandling = DateParseHandling.DateTimeOffset;
  471. IList<object> l = new List<object>();
  472. serializer.Populate(reader, l);
  473. Assert.AreEqual(typeof(DateTimeOffset), l[0].GetType());
  474. Assert.AreEqual(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), l[0]);
  475. Assert.AreEqual(DateParseHandling.DateTime, reader.DateParseHandling);
  476. }
  477. #endif
  478. public class BaseClass
  479. {
  480. internal bool IsTransient { get; set; }
  481. }
  482. public class ChildClass : BaseClass
  483. {
  484. public new bool IsTransient { get; set; }
  485. }
  486. [Test]
  487. public void NewProperty()
  488. {
  489. Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClass { IsTransient = true }));
  490. var childClass = JsonConvert.DeserializeObject<ChildClass>(@"{""IsTransient"":true}");
  491. Assert.AreEqual(true, childClass.IsTransient);
  492. }
  493. public class BaseClassVirtual
  494. {
  495. internal virtual bool IsTransient { get; set; }
  496. }
  497. public class ChildClassVirtual : BaseClassVirtual
  498. {
  499. public new virtual bool IsTransient { get; set; }
  500. }
  501. [Test]
  502. public void NewPropertyVirtual()
  503. {
  504. Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClassVirtual { IsTransient = true }));
  505. var childClass = JsonConvert.DeserializeObject<ChildClassVirtual>(@"{""IsTransient"":true}");
  506. Assert.AreEqual(true, childClass.IsTransient);
  507. }
  508. public class ResponseWithNewGenericProperty<T> : SimpleResponse
  509. {
  510. public new T Data { get; set; }
  511. }
  512. public class ResponseWithNewGenericPropertyVirtual<T> : SimpleResponse
  513. {
  514. public new virtual T Data { get; set; }
  515. }
  516. public class ResponseWithNewGenericPropertyOverride<T> : ResponseWithNewGenericPropertyVirtual<T>
  517. {
  518. public override T Data { get; set; }
  519. }
  520. public abstract class SimpleResponse
  521. {
  522. public string Result { get; set; }
  523. public string Message { get; set; }
  524. public object Data { get; set; }
  525. protected SimpleResponse()
  526. {
  527. }
  528. protected SimpleResponse(string message)
  529. {
  530. Message = message;
  531. }
  532. }
  533. [Test]
  534. public void CanSerializeWithBuiltInTypeAsGenericArgument()
  535. {
  536. var input = new ResponseWithNewGenericProperty<int>()
  537. {
  538. Message = "Trying out integer as type parameter",
  539. Data = 25,
  540. Result = "This should be fine"
  541. };
  542. var json = JsonConvert.SerializeObject(input);
  543. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<int>>(json);
  544. Assert.AreEqual(input.Data, deserialized.Data);
  545. Assert.AreEqual(input.Message, deserialized.Message);
  546. Assert.AreEqual(input.Result, deserialized.Result);
  547. }
  548. [Test]
  549. public void CanSerializeWithBuiltInTypeAsGenericArgumentVirtual()
  550. {
  551. var input = new ResponseWithNewGenericPropertyVirtual<int>()
  552. {
  553. Message = "Trying out integer as type parameter",
  554. Data = 25,
  555. Result = "This should be fine"
  556. };
  557. var json = JsonConvert.SerializeObject(input);
  558. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyVirtual<int>>(json);
  559. Assert.AreEqual(input.Data, deserialized.Data);
  560. Assert.AreEqual(input.Message, deserialized.Message);
  561. Assert.AreEqual(input.Result, deserialized.Result);
  562. }
  563. [Test]
  564. public void CanSerializeWithBuiltInTypeAsGenericArgumentOverride()
  565. {
  566. var input = new ResponseWithNewGenericPropertyOverride<int>()
  567. {
  568. Message = "Trying out integer as type parameter",
  569. Data = 25,
  570. Result = "This should be fine"
  571. };
  572. var json = JsonConvert.SerializeObject(input);
  573. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyOverride<int>>(json);
  574. Assert.AreEqual(input.Data, deserialized.Data);
  575. Assert.AreEqual(input.Message, deserialized.Message);
  576. Assert.AreEqual(input.Result, deserialized.Result);
  577. }
  578. [Test]
  579. public void CanSerializedWithGenericClosedTypeAsArgument()
  580. {
  581. var input = new ResponseWithNewGenericProperty<List<int>>()
  582. {
  583. Message = "More complex case - generic list of int",
  584. Data = Enumerable.Range(50, 70).ToList(),
  585. Result = "This should be fine too"
  586. };
  587. var json = JsonConvert.SerializeObject(input);
  588. var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<List<int>>>(json);
  589. CollectionAssert.AreEqual(input.Data, deserialized.Data);
  590. Assert.AreEqual(input.Message, deserialized.Message);
  591. Assert.AreEqual(input.Result, deserialized.Result);
  592. }
  593. [Test]
  594. public void DeserializeJObjectWithComments()
  595. {
  596. string json = @"/* Test */
  597. {
  598. /*Test*/""A"":/* Test */true/* Test */,
  599. /* Test */""B"":/* Test */false/* Test */,
  600. /* Test */""C"":/* Test */[
  601. /* Test */
  602. 1/* Test */
  603. ]/* Test */
  604. }
  605. /* Test */";
  606. JObject o = (JObject)JsonConvert.DeserializeObject(json);
  607. Assert.AreEqual(3, o.Count);
  608. Assert.AreEqual(true, (bool)o["A"]);
  609. Assert.AreEqual(false, (bool)o["B"]);
  610. Assert.AreEqual(3, o["C"].Count());
  611. Assert.AreEqual(JTokenType.Comment, o["C"][0].Type);
  612. Assert.AreEqual(1, (int)o["C"][1]);
  613. Assert.AreEqual(JTokenType.Comment, o["C"][2].Type);
  614. Assert.IsTrue(JToken.DeepEquals(o, JObject.Parse(json)));
  615. json = @"{/* Test */}";
  616. o = (JObject)JsonConvert.DeserializeObject(json);
  617. Assert.AreEqual(0, o.Count);
  618. Assert.IsTrue(JToken.DeepEquals(o, JObject.Parse(json)));
  619. json = @"{""A"": true/* Test */}";
  620. o = (JObject)JsonConvert.DeserializeObject(json);
  621. Assert.AreEqual(1, o.Count);
  622. Assert.AreEqual(true, (bool)o["A"]);
  623. Assert.IsTrue(JToken.DeepEquals(o, JObject.Parse(json)));
  624. }
  625. public class CommentTestObject
  626. {
  627. public bool? A { get; set; }
  628. }
  629. [Test]
  630. public void DeserializeCommentTestObjectWithComments()
  631. {
  632. CommentTestObject o = JsonConvert.DeserializeObject<CommentTestObject>(@"{/* Test */}");
  633. Assert.AreEqual(null, o.A);
  634. o = JsonConvert.DeserializeObject<CommentTestObject>(@"{""A"": true/* Test */}");
  635. Assert.AreEqual(true, o.A);
  636. }
  637. [Test]
  638. public void JsonSerializerProperties()
  639. {
  640. JsonSerializer serializer = new JsonSerializer();
  641. DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
  642. serializer.Binder = customBinder;
  643. Assert.AreEqual(customBinder, serializer.Binder);
  644. serializer.CheckAdditionalContent = true;
  645. Assert.AreEqual(true, serializer.CheckAdditionalContent);
  646. serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
  647. Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializer.ConstructorHandling);
  648. #if !(NETFX_CORE || DNXCORE50)
  649. serializer.Context = new StreamingContext(StreamingContextStates.Other);
  650. Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializer.Context);
  651. #endif
  652. CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
  653. serializer.ContractResolver = resolver;
  654. Assert.AreEqual(resolver, serializer.ContractResolver);
  655. serializer.Converters.Add(new StringEnumConverter());
  656. Assert.AreEqual(1, serializer.Converters.Count);
  657. serializer.Culture = new CultureInfo("en-nz");
  658. Assert.AreEqual("en-NZ", serializer.Culture.ToString());
  659. serializer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
  660. Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializer.DateFormatHandling);
  661. serializer.DateFormatString = "yyyy";
  662. Assert.AreEqual("yyyy", serializer.DateFormatString);
  663. serializer.DateParseHandling = DateParseHandling.None;
  664. Assert.AreEqual(DateParseHandling.None, serializer.DateParseHandling);
  665. serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  666. Assert.AreEqual(DateTimeZoneHandling.Utc, serializer.DateTimeZoneHandling);
  667. serializer.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
  668. Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializer.DefaultValueHandling);
  669. serializer.FloatFormatHandling = FloatFormatHandling.Symbol;
  670. Assert.AreEqual(FloatFormatHandling.Symbol, serializer.FloatFormatHandling);
  671. serializer.FloatParseHandling = FloatParseHandling.Decimal;
  672. Assert.AreEqual(FloatParseHandling.Decimal, serializer.FloatParseHandling);
  673. serializer.Formatting = Formatting.Indented;
  674. Assert.AreEqual(Formatting.Indented, serializer.Formatting);
  675. serializer.MaxDepth = 9001;
  676. Assert.AreEqual(9001, serializer.MaxDepth);
  677. serializer.MissingMemberHandling = MissingMemberHandling.Error;
  678. Assert.AreEqual(MissingMemberHandling.Error, serializer.MissingMemberHandling);
  679. serializer.NullValueHandling = NullValueHandling.Ignore;
  680. Assert.AreEqual(NullValueHandling.Ignore, serializer.NullValueHandling);
  681. serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
  682. Assert.AreEqual(ObjectCreationHandling.Replace, serializer.ObjectCreationHandling);
  683. serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
  684. Assert.AreEqual(PreserveReferencesHandling.All, serializer.PreserveReferencesHandling);
  685. serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  686. Assert.AreEqual(ReferenceLoopHandling.Ignore, serializer.ReferenceLoopHandling);
  687. IdReferenceResolver referenceResolver = new IdReferenceResolver();
  688. serializer.ReferenceResolver = referenceResolver;
  689. Assert.AreEqual(referenceResolver, serializer.ReferenceResolver);
  690. serializer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
  691. Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializer.StringEscapeHandling);
  692. MemoryTraceWriter traceWriter = new MemoryTraceWriter();
  693. serializer.TraceWriter = traceWriter;
  694. Assert.AreEqual(traceWriter, serializer.TraceWriter);
  695. #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20 || DNXCORE50)
  696. serializer.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
  697. Assert.AreEqual(FormatterAssemblyStyle.Full, serializer.TypeNameAssemblyFormat);
  698. #endif
  699. serializer.TypeNameHandling = TypeNameHandling.All;
  700. Assert.AreEqual(TypeNameHandling.All, serializer.TypeNameHandling);
  701. }
  702. [Test]
  703. public void JsonSerializerSettingsProperties()
  704. {
  705. JsonSerializerSettings settings = new JsonSerializerSettings();
  706. DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
  707. settings.Binder = customBinder;
  708. Assert.AreEqual(customBinder, settings.Binder);
  709. settings.CheckAdditionalContent = true;
  710. Assert.AreEqual(true, settings.CheckAdditionalContent);
  711. settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
  712. Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, settings.ConstructorHandling);
  713. #if !(NETFX_CORE || DNXCORE50)
  714. settings.Context = new StreamingContext(StreamingContextStates.Other);
  715. Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), settings.Context);
  716. #endif
  717. CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
  718. settings.ContractResolver = resolver;
  719. Assert.AreEqual(resolver, settings.ContractResolver);
  720. settings.Converters.Add(new StringEnumConverter());
  721. Assert.AreEqual(1, settings.Converters.Count);
  722. settings.Culture = new CultureInfo("en-nz");
  723. Assert.AreEqual("en-NZ", settings.Culture.ToString());
  724. settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
  725. Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, settings.DateFormatHandling);
  726. settings.DateFormatString = "yyyy";
  727. Assert.AreEqual("yyyy", settings.DateFormatString);
  728. settings.DateParseHandling = DateParseHandling.None;
  729. Assert.AreEqual(DateParseHandling.None, settings.DateParseHandling);
  730. settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  731. Assert.AreEqual(DateTimeZoneHandling.Utc, settings.DateTimeZoneHandling);
  732. settings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
  733. Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, settings.DefaultValueHandling);
  734. settings.FloatFormatHandling = FloatFormatHandling.Symbol;
  735. Assert.AreEqual(FloatFormatHandling.Symbol, settings.FloatFormatHandling);
  736. settings.FloatParseHandling = FloatParseHandling.Decimal;
  737. Assert.AreEqual(FloatParseHandling.Decimal, settings.FloatParseHandling);
  738. settings.Formatting = Formatting.Indented;
  739. Assert.AreEqual(Formatting.Indented, settings.Formatting);
  740. settings.MaxDepth = 9001;
  741. Assert.AreEqual(9001, settings.MaxDepth);
  742. settings.MissingMemberHandling = MissingMemberHandling.Error;
  743. Assert.AreEqual(MissingMemberHandling.Error, settings.MissingMemberHandling);
  744. settings.NullValueHandling = NullValueHandling.Ignore;
  745. Assert.AreEqual(NullValueHandling.Ignore, settings.NullValueHandling);
  746. settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
  747. Assert.AreEqual(ObjectCreationHandling.Replace, settings.ObjectCreationHandling);
  748. settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
  749. Assert.AreEqual(PreserveReferencesHandling.All, settings.PreserveReferencesHandling);
  750. settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  751. Assert.AreEqual(ReferenceLoopHandling.Ignore, settings.ReferenceLoopHandling);
  752. IdReferenceResolver referenceResolver = new IdReferenceResolver();
  753. #pragma warning disable 618
  754. settings.ReferenceResolver = referenceResolver;
  755. Assert.AreEqual(referenceResolver, settings.ReferenceResolver);
  756. #pragma warning restore 618
  757. Assert.AreEqual(referenceResolver, settings.ReferenceResolverProvider());
  758. settings.ReferenceResolverProvider = () => referenceResolver;
  759. Assert.AreEqual(referenceResolver, settings.ReferenceResolverProvider());
  760. settings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
  761. Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, settings.StringEscapeHandling);
  762. MemoryTraceWriter traceWriter = new MemoryTraceWriter();
  763. settings.TraceWriter = traceWriter;
  764. Assert.AreEqual(traceWriter, settings.TraceWriter);
  765. #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20 || DNXCORE50)
  766. settings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
  767. Assert.AreEqual(FormatterAssemblyStyle.Full, settings.TypeNameAssemblyFormat);
  768. #endif
  769. settings.TypeNameHandling = TypeNameHandling.All;
  770. Assert.AreEqual(TypeNameHandling.All, settings.TypeNameHandling);
  771. }
  772. [Test]
  773. public void JsonSerializerProxyProperties()
  774. {
  775. JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer()));
  776. DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
  777. serializerProxy.Binder = customBinder;
  778. Assert.AreEqual(customBinder, serializerProxy.Binder);
  779. serializerProxy.CheckAdditionalContent = true;
  780. Assert.AreEqual(true, serializerProxy.CheckAdditionalContent);
  781. serializerProxy.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
  782. Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializerProxy.ConstructorHandling);
  783. #if !(NETFX_CORE || DNXCORE50)
  784. serializerProxy.Context = new StreamingContext(StreamingContextStates.Other);
  785. Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializerProxy.Context);
  786. #endif
  787. CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
  788. serializerProxy.ContractResolver = resolver;
  789. Assert.AreEqual(resolver, serializerProxy.ContractResolver);
  790. serializerProxy.Converters.Add(new StringEnumConverter());
  791. Assert.AreEqual(1, serializerProxy.Converters.Count);
  792. serializerProxy.Culture = new CultureInfo("en-nz");
  793. Assert.AreEqual("en-NZ", serializerProxy.Culture.ToString());
  794. serializerProxy.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
  795. Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializerProxy.DateFormatHandling);
  796. serializerProxy.DateFormatString = "yyyy";
  797. Assert.AreEqual("yyyy", serializerProxy.DateFormatString);
  798. serializerProxy.DateParseHandling = DateParseHandling.None;
  799. Assert.AreEqual(DateParseHandling.None, serializerProxy.DateParseHandling);
  800. serializerProxy.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
  801. Assert.AreEqual(DateTimeZoneHandling.Utc, serializerProxy.DateTimeZoneHandling);
  802. serializerProxy.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
  803. Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializerProxy.DefaultValueHandling);
  804. serializerProxy.FloatFormatHandling = FloatFormatHandling.Symbol;
  805. Assert.AreEqual(FloatFormatHandling.Symbol, serializerProxy.FloatFormatHandling);
  806. serializerProxy.FloatParseHandling = FloatParseHandling.Decimal;
  807. Assert.AreEqual(FloatParseHandling.Decimal, serializerProxy.FloatParseHandling);
  808. serializerProxy.Formatting = Formatting.Indented;
  809. Assert.AreEqual(Formatting.Indented, serializerProxy.Formatting);
  810. serializerProxy.MaxDepth = 9001;
  811. Assert.AreEqual(9001, serializerProxy.MaxDepth);
  812. serializerProxy.MissingMemberHandling = MissingMemberHandling.Error;
  813. Assert.AreEqual(MissingMemberHandling.Error, serializerProxy.MissingMemberHandling);
  814. serializerProxy.NullValueHandling = NullValueHandling.Ignore;
  815. Assert.AreEqual(NullValueHandling.Ignore, serializerProxy.NullValueHandling);
  816. serializerProxy.ObjectCreationHandling = ObjectCreationHandling.Replace;
  817. Assert.AreEqual(ObjectCreationHandling.Replace, serializerProxy.ObjectCreationHandling);
  818. serializerProxy.PreserveReferencesHandling = PreserveReferencesHandling.All;
  819. Assert.AreEqual(PreserveReferencesHandling.All, serializerProxy.PreserveReferencesHandling);
  820. serializerProxy.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  821. Assert.AreEqual(ReferenceLoopHandling.Ignore, serializerProxy.ReferenceLoopHandling);
  822. IdReferenceResolver referenceResolver = new IdReferenceResolver();
  823. serializerProxy.ReferenceResolver = referenceResolver;
  824. Assert.AreEqual(referenceResolver, serializerProxy.ReferenceResolver);
  825. serializerProxy.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
  826. Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializerProxy.StringEscapeHandling);
  827. MemoryTraceWriter traceWriter = new MemoryTraceWriter();
  828. serializerProxy.TraceWriter = traceWriter;
  829. Assert.AreEqual(traceWriter, serializerProxy.TraceWriter);
  830. #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20 || DNXCORE50)
  831. serializerProxy.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
  832. Assert.AreEqual(FormatterAssemblyStyle.Full, serializerProxy.TypeNameAssemblyFormat);
  833. #endif
  834. serializerProxy.TypeNameHandling = TypeNameHandling.All;
  835. Assert.AreEqual(TypeNameHandling.All, serializerProxy.TypeNameHandling);
  836. }
  837. #if !(NETFX_CORE || PORTABLE || PORTABLE40 || DNXCORE50)
  838. [Test]
  839. public void DeserializeISerializableIConvertible()
  840. {
  841. Ratio ratio = new Ratio(2, 1);
  842. string json = JsonConvert.SerializeObject(ratio);
  843. Assert.AreEqual(@"{""n"":2,""d"":1}", json);
  844. Ratio ratio2 = JsonConvert.DeserializeObject<Ratio>(json);
  845. Assert.AreEqual(ratio.Denominator, ratio2.Denominator);
  846. Assert.AreEqual(ratio.Numerator, ratio2.Numerator);
  847. }
  848. public class PreserveReferencesCallbackTestObject : ISerializable
  849. {
  850. internal string _stringValue;
  851. internal int _intValue;
  852. internal PersonReference _person1;
  853. internal PersonReference _person2;
  854. internal PersonReference _person3;
  855. internal PreserveReferencesCallbackTestObject _parent;
  856. internal SerializationInfo _serializationInfo;
  857. public PreserveReferencesCallbackTestObject(string stringValue, int intValue, PersonReference p1, PersonReference p2, PersonReference p3)
  858. {
  859. _stringValue = stringValue;
  860. _intValue = intValue;
  861. _person1 = p1;
  862. _person2 = p2;
  863. _person3 = p3;
  864. }
  865. protected PreserveReferencesCallbackTestObject(SerializationInfo info, StreamingContext context)
  866. {
  867. _serializationInfo = info;
  868. }
  869. public void GetObjectData(SerializationInfo info, StreamingContext context)
  870. {
  871. info.AddValue("stringValue", _stringValue);
  872. info.AddValue("intValue", _intValue);
  873. info.AddValue("person1", _person1, typeof(PersonReference));
  874. info.AddValue("person2", _person2, typeof(PersonReference));
  875. info.AddValue("person3", _person3, typeof(PersonReference));
  876. info.AddValue("parent", _parent, typeof(PreserveReferencesCallbackTestObject));
  877. }
  878. [OnDeserialized]
  879. private void OnDeserializedMethod(StreamingContext context)
  880. {
  881. if (_serializationInfo == null)
  882. return;
  883. _stringValue = _serializationInfo.GetString("stringValue");
  884. _intValue = _serializationInfo.GetInt32("intValue");
  885. _person1 = (PersonReference)_serializationInfo.GetValue("person1", typeof(PersonReference));
  886. _person2 = (PersonReference)_serializationInfo.GetValue("person2", typeof(PersonReference));
  887. _person3 = (PersonReference)_serializationInfo.GetValue("person3", typeof(PersonReference));
  888. _parent = (PreserveReferencesCallbackTestObject)_serializationInfo.GetValue("parent", typeof(PreserveReferencesCallbackTestObject));
  889. _serializationInfo = null;
  890. }
  891. }
  892. [Test]
  893. public void PreserveReferencesCallbackTest()
  894. {
  895. var p1 = new PersonReference
  896. {
  897. Name = "John Smith"
  898. };
  899. var p2 = new PersonReference
  900. {
  901. Name = "Mary Sue",
  902. };
  903. p1.Spouse = p2;
  904. p2.Spouse = p1;
  905. var obj = new PreserveReferencesCallbackTestObject("string!", 42, p1, p2, p1);
  906. obj._parent = obj;
  907. var settings = new JsonSerializerSettings
  908. {
  909. PreserveReferencesHandling = PreserveReferencesHandling.All,
  910. Formatting = Formatting.Indented
  911. };
  912. string json = JsonConvert.SerializeObject(obj, settings);
  913. StringAssert.AreEqual(json, @"{
  914. ""$id"": ""1"",
  915. ""stringValue"": ""string!"",
  916. ""intValue"": 42,
  917. ""person1"": {
  918. ""$id"": ""2"",
  919. ""Name"": ""John Smith"",
  920. ""Spouse"": {
  921. ""$id"": ""3"",
  922. ""Name"": ""Mary Sue"",
  923. ""Spouse"": {
  924. ""$ref"": ""2""
  925. }
  926. }
  927. },
  928. ""person2"": {
  929. ""$ref"": ""3""
  930. },
  931. ""person3"": {
  932. ""$ref"": ""2""
  933. },
  934. ""parent"": {
  935. ""$ref"": ""1""
  936. }
  937. }");
  938. PreserveReferencesCallbackTestObject obj2 = JsonConvert.DeserializeObject<PreserveReferencesCallbackTestObject>(json);
  939. Assert.AreEqual(obj._stringValue, obj2._stringValue);
  940. Assert.AreEqual(obj._intValue, obj2._intValue);
  941. Assert.AreEqual(obj._person1.Name, obj2._person1.Name);
  942. Assert.AreEqual(obj._person2.Name, obj2._person2.Name);
  943. Assert.AreEqual(obj._person3.Name, obj2._person3.Name);
  944. Assert.AreEqual(obj2._person1, obj2._person3);
  945. Assert.AreEqual(obj2._person1.Spouse, obj2._person2);
  946. Assert.AreEqual(obj2._person2.Spouse, obj2._person1);
  947. Assert.AreEqual(obj2._parent, obj2);
  948. }
  949. #endif
  950. [Test]
  951. public void DeserializeLargeFloat()
  952. {
  953. object o = JsonConvert.DeserializeObject("100000000000000000000000000000000000000.0");
  954. CustomAssert.IsInstanceOfType(typeof(double), o);
  955. Assert.IsTrue(MathUtils.ApproxEquals(1E+38, (double)o));
  956. }
  957. [Test]
  958. public void SerializeDeserializeRegex()
  959. {
  960. Regex regex = new Regex("(hi)", RegexOptions.CultureInvariant);
  961. string json = JsonConvert.SerializeObject(regex, Formatting.Indented);
  962. Regex r2 = JsonConvert.DeserializeObject<Regex>(json);
  963. Assert.AreEqual("(hi)", r2.ToString());
  964. Assert.AreEqual(RegexOptions.CultureInvariant, r2.Options);
  965. }
  966. [Test]
  967. public void EmbedJValueStringInNewJObject()
  968. {
  969. string s = null;
  970. var v = new JValue(s);
  971. var o = JObject.FromObject(new { title = v });
  972. JObject oo = new JObject
  973. {
  974. { "title", v }
  975. };
  976. string output = o.ToString();
  977. Assert.AreEqual(null, v.Value);
  978. Assert.AreEqual(JTokenType.String, v.Type);
  979. StringAssert.AreEqual(@"{
  980. ""title"": null
  981. }", output);
  982. }
  983. // bug: the generic member (T) that hides the base member will not
  984. // be used when serializing and deserializing the object,
  985. // resulting in unexpected behavior during serialization and deserialization.
  986. public class Foo1
  987. {
  988. public object foo { get; set; }
  989. }
  990. public class Bar1
  991. {
  992. public object bar { get; set; }
  993. }
  994. public class Foo1<T> : Foo1
  995. {
  996. public new T foo { get; set; }
  997. public T foo2 { get; set; }
  998. }
  999. public class FooBar1 : Foo1
  1000. {
  1001. public new Bar1 foo { get; set; }
  1002. }
  1003. [Test]
  1004. public void BaseClassSerializesAsExpected()
  1005. {
  1006. var original = new Foo1 { foo = "value" };
  1007. var json = JsonConvert.SerializeObject(original);
  1008. var expectedJson = @"{""foo"":""value""}";
  1009. Assert.AreEqual(expectedJson, json); // passes
  1010. }
  1011. [Test]
  1012. public void BaseClassDeserializesAsExpected()
  1013. {
  1014. var json = @"{""foo"":""value""}";
  1015. var deserialized = JsonConvert.DeserializeObject<Foo1>(json);
  1016. Assert.AreEqual("value", deserialized.foo); // passes
  1017. }
  1018. [Test]
  1019. public void DerivedClassHidingBasePropertySerializesAsExpected()
  1020. {
  1021. var original = new FooBar1 { foo = new Bar1 { bar = "value" } };
  1022. var json = JsonConvert.SerializeObject(original);
  1023. var expectedJson = @"{""foo"":{""bar"":""value""}}";
  1024. Assert.AreEqual(expectedJson, json); // passes
  1025. }
  1026. [Test]
  1027. public void DerivedClassHidingBasePropertyDeserializesAsExpected()
  1028. {
  1029. var json = @"{""foo"":{""bar"":""value""}}";
  1030. var deserialized = JsonConvert.DeserializeObject<FooBar1>(json);
  1031. Assert.IsNotNull(deserialized.foo); // passes
  1032. Assert.AreEqual("value", deserialized.foo.bar); // passes
  1033. }
  1034. [Test]
  1035. public void DerivedGenericClassHidingBasePropertySerializesAsExpected()
  1036. {
  1037. var original = new Foo1<Bar1> { foo = new Bar1 { bar = "value" }, foo2 = new Bar1 { bar = "value2" } };
  1038. var json = JsonConvert.SerializeObject(original);
  1039. var expectedJson = @"{""foo"":{""bar"":""value""},""foo2"":{""bar"":""value2""}}";
  1040. Assert.AreEqual(expectedJson, json);
  1041. }
  1042. [Test]
  1043. public void DerivedGenericClassHidingBasePropertyDeserializesAsExpected()
  1044. {
  1045. var json = @"{""foo"":{""bar"":""value""},""foo2"":{""bar"":""value2""}}";
  1046. var deserialized = JsonConvert.DeserializeObject<Foo1<Bar1>>(json);
  1047. Assert.IsNotNull(deserialized.foo2); // passes (bug only occurs for generics that /hide/ another property)
  1048. Assert.AreEqual("value2", deserialized.foo2.bar); // also passes, with no issue
  1049. Assert.IsNotNull(deserialized.foo);
  1050. Assert.AreEqual("value", deserialized.foo.bar);
  1051. }
  1052. #if !(NETFX_CORE || DNXCORE50)
  1053. [Test]
  1054. public void ConversionOperator()
  1055. {
  1056. // Creating a simple dictionary that has a non-string key
  1057. var dictStore = new Dictionary<DictionaryKeyCast, int>();
  1058. for (var i = 0; i < 800; i++)
  1059. {
  1060. dictStore.Add(new DictionaryKeyCast(i.ToString(CultureInfo.InvariantCulture), i), i);
  1061. }
  1062. var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
  1063. var jsonSerializer = JsonSerializer.Create(settings);

Large files files are truncated, but you can click here to view the full file