PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/Json45r7/Source/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs

https://bitbucket.org/wantstudios/bitbucketclient
C# | 1603 lines | 1547 code | 25 blank | 31 comment | 3 complexity | 5e52137d1c1b84d11f8189949b809476 MD5 | raw file
  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. #if !PORTABLE
  26. #if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
  27. using System.Dynamic;
  28. #endif
  29. using Newtonsoft.Json.Tests.Linq;
  30. using global::System;
  31. using global::System.Collections;
  32. using global::System.Collections.Generic;
  33. using global::System.Globalization;
  34. using global::System.Runtime.Serialization.Formatters;
  35. using global::Newtonsoft.Json.Linq;
  36. using global::Newtonsoft.Json.Serialization;
  37. using global::Newtonsoft.Json.Tests.TestObjects;
  38. #if !NETFX_CORE
  39. using global::NUnit.Framework;
  40. #else
  41. using global::Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  42. using TestFixture = global::Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  43. using Test = global::Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  44. #endif
  45. using global::Newtonsoft.Json.Utilities;
  46. using global::System.Net;
  47. using global::System.Runtime.Serialization;
  48. using global::System.IO;
  49. namespace Newtonsoft.Json.Tests.Serialization
  50. {
  51. [TestFixture]
  52. public class TypeNameHandlingTests : TestFixtureBase
  53. {
  54. public class Wrapper
  55. {
  56. public IList<EmployeeReference> Array { get; set; }
  57. public IDictionary<string, EmployeeReference> Dictionary { get; set; }
  58. }
  59. [Test]
  60. public void SerializeWrapper()
  61. {
  62. Wrapper wrapper = new Wrapper();
  63. wrapper.Array = new List<EmployeeReference>
  64. {
  65. new EmployeeReference()
  66. };
  67. wrapper.Dictionary = new Dictionary<string, EmployeeReference>
  68. {
  69. {"First", new EmployeeReference()}
  70. };
  71. string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented, new JsonSerializerSettings
  72. {
  73. TypeNameHandling = TypeNameHandling.Auto
  74. });
  75. Assert.AreEqual(@"{
  76. ""Array"": [
  77. {
  78. ""$id"": ""1"",
  79. ""Name"": null,
  80. ""Manager"": null
  81. }
  82. ],
  83. ""Dictionary"": {
  84. ""First"": {
  85. ""$id"": ""2"",
  86. ""Name"": null,
  87. ""Manager"": null
  88. }
  89. }
  90. }", json);
  91. Wrapper w2 = JsonConvert.DeserializeObject<Wrapper>(json);
  92. CustomAssert.IsInstanceOfType(typeof (List<EmployeeReference>), w2.Array);
  93. CustomAssert.IsInstanceOfType(typeof (Dictionary<string, EmployeeReference>), w2.Dictionary);
  94. }
  95. [Test]
  96. public void WriteTypeNameForObjects()
  97. {
  98. string employeeRef = ReflectionUtils.GetTypeName(typeof (EmployeeReference), FormatterAssemblyStyle.Simple);
  99. EmployeeReference employee = new EmployeeReference();
  100. string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings
  101. {
  102. TypeNameHandling = TypeNameHandling.Objects
  103. });
  104. Assert.AreEqual(@"{
  105. ""$id"": ""1"",
  106. ""$type"": """ + employeeRef + @""",
  107. ""Name"": null,
  108. ""Manager"": null
  109. }", json);
  110. }
  111. [Test]
  112. public void DeserializeTypeName()
  113. {
  114. string employeeRef = ReflectionUtils.GetTypeName(typeof (EmployeeReference), FormatterAssemblyStyle.Simple);
  115. string json = @"{
  116. ""$id"": ""1"",
  117. ""$type"": """ + employeeRef + @""",
  118. ""Name"": ""Name!"",
  119. ""Manager"": null
  120. }";
  121. object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  122. {
  123. TypeNameHandling = TypeNameHandling.Objects
  124. });
  125. CustomAssert.IsInstanceOfType(typeof (EmployeeReference), employee);
  126. Assert.AreEqual("Name!", ((EmployeeReference) employee).Name);
  127. }
  128. #if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
  129. [Test]
  130. public void DeserializeTypeNameFromGacAssembly()
  131. {
  132. string cookieRef = ReflectionUtils.GetTypeName(typeof (Cookie), FormatterAssemblyStyle.Simple);
  133. string json = @"{
  134. ""$id"": ""1"",
  135. ""$type"": """ + cookieRef + @"""
  136. }";
  137. object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  138. {
  139. TypeNameHandling = TypeNameHandling.Objects
  140. });
  141. CustomAssert.IsInstanceOfType(typeof (Cookie), cookie);
  142. }
  143. #endif
  144. [Test]
  145. public void SerializeGenericObjectListWithTypeName()
  146. {
  147. string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
  148. string personRef = typeof (Person).AssemblyQualifiedName;
  149. List<object> values = new List<object>
  150. {
  151. new EmployeeReference
  152. {
  153. Name = "Bob",
  154. Manager = new EmployeeReference {Name = "Frank"}
  155. },
  156. new Person
  157. {
  158. Department = "Department",
  159. BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc),
  160. LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc)
  161. },
  162. "String!",
  163. int.MinValue
  164. };
  165. string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
  166. {
  167. TypeNameHandling = TypeNameHandling.Objects,
  168. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  169. });
  170. Assert.AreEqual(@"[
  171. {
  172. ""$id"": ""1"",
  173. ""$type"": """ + employeeRef + @""",
  174. ""Name"": ""Bob"",
  175. ""Manager"": {
  176. ""$id"": ""2"",
  177. ""$type"": """ + employeeRef + @""",
  178. ""Name"": ""Frank"",
  179. ""Manager"": null
  180. }
  181. },
  182. {
  183. ""$type"": """ + personRef + @""",
  184. ""Name"": null,
  185. ""BirthDate"": ""2000-12-30T00:00:00Z"",
  186. ""LastModified"": ""2000-12-30T00:00:00Z""
  187. },
  188. ""String!"",
  189. -2147483648
  190. ]", json);
  191. }
  192. [Test]
  193. public void DeserializeGenericObjectListWithTypeName()
  194. {
  195. string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
  196. string personRef = typeof (Person).AssemblyQualifiedName;
  197. string json = @"[
  198. {
  199. ""$id"": ""1"",
  200. ""$type"": """ + employeeRef + @""",
  201. ""Name"": ""Bob"",
  202. ""Manager"": {
  203. ""$id"": ""2"",
  204. ""$type"": """ + employeeRef + @""",
  205. ""Name"": ""Frank"",
  206. ""Manager"": null
  207. }
  208. },
  209. {
  210. ""$type"": """ + personRef + @""",
  211. ""Name"": null,
  212. ""BirthDate"": ""\/Date(978134400000)\/"",
  213. ""LastModified"": ""\/Date(978134400000)\/""
  214. },
  215. ""String!"",
  216. -2147483648
  217. ]";
  218. List<object> values = (List<object>) JsonConvert.DeserializeObject(json, typeof (List<object>), new JsonSerializerSettings
  219. {
  220. TypeNameHandling = TypeNameHandling.Objects,
  221. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  222. });
  223. Assert.AreEqual(4, values.Count);
  224. EmployeeReference e = (EmployeeReference) values[0];
  225. Person p = (Person) values[1];
  226. Assert.AreEqual("Bob", e.Name);
  227. Assert.AreEqual("Frank", e.Manager.Name);
  228. Assert.AreEqual(null, p.Name);
  229. Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate);
  230. Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified);
  231. Assert.AreEqual("String!", values[2]);
  232. Assert.AreEqual((long) int.MinValue, values[3]);
  233. }
  234. [Test]
  235. public void DeserializeWithBadTypeName()
  236. {
  237. string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
  238. string personRef = typeof (Person).AssemblyQualifiedName;
  239. string json = @"{
  240. ""$id"": ""1"",
  241. ""$type"": """ + employeeRef + @""",
  242. ""Name"": ""Name!"",
  243. ""Manager"": null
  244. }";
  245. try
  246. {
  247. JsonConvert.DeserializeObject(json, typeof (Person), new JsonSerializerSettings
  248. {
  249. TypeNameHandling = TypeNameHandling.Objects,
  250. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  251. });
  252. }
  253. catch (JsonSerializationException ex)
  254. {
  255. Assert.IsTrue(ex.Message.StartsWith(@"Type specified in JSON '" + employeeRef + @"' is not compatible with '" + personRef + @"'."));
  256. }
  257. }
  258. [Test]
  259. public void DeserializeTypeNameWithNoTypeNameHandling()
  260. {
  261. string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName;
  262. string json = @"{
  263. ""$id"": ""1"",
  264. ""$type"": """ + employeeRef + @""",
  265. ""Name"": ""Name!"",
  266. ""Manager"": null
  267. }";
  268. JObject o = (JObject) JsonConvert.DeserializeObject(json);
  269. Assert.AreEqual(@"{
  270. ""Name"": ""Name!"",
  271. ""Manager"": null
  272. }", o.ToString());
  273. }
  274. [Test]
  275. public void DeserializeTypeNameOnly()
  276. {
  277. string json = @"{
  278. ""$id"": ""1"",
  279. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
  280. ""Name"": ""Name!"",
  281. ""Manager"": null
  282. }";
  283. ExceptionAssert.Throws<JsonSerializationException>(
  284. "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved. Path '$type', line 3, position 56.",
  285. () =>
  286. {
  287. JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  288. {
  289. TypeNameHandling = TypeNameHandling.Objects
  290. });
  291. });
  292. }
  293. public interface ICorrelatedMessage
  294. {
  295. string CorrelationId { get; set; }
  296. }
  297. public class SendHttpRequest : ICorrelatedMessage
  298. {
  299. public SendHttpRequest()
  300. {
  301. RequestEncoding = "UTF-8";
  302. Method = "GET";
  303. }
  304. public string Method { get; set; }
  305. public Dictionary<string, string> Headers { get; set; }
  306. public string Url { get; set; }
  307. public Dictionary<string, string> RequestData;
  308. public string RequestBodyText { get; set; }
  309. public string User { get; set; }
  310. public string Passwd { get; set; }
  311. public string RequestEncoding { get; set; }
  312. public string CorrelationId { get; set; }
  313. }
  314. [Test]
  315. public void DeserializeGenericTypeName()
  316. {
  317. string typeName = typeof (SendHttpRequest).AssemblyQualifiedName;
  318. string json = @"{
  319. ""$type"": """ + typeName + @""",
  320. ""RequestData"": {
  321. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
  322. ""Id"": ""siedemnaście"",
  323. ""X"": ""323""
  324. },
  325. ""Method"": ""GET"",
  326. ""Url"": ""http://www.onet.pl"",
  327. ""RequestEncoding"": ""UTF-8"",
  328. ""CorrelationId"": ""xyz""
  329. }";
  330. ICorrelatedMessage message = JsonConvert.DeserializeObject<ICorrelatedMessage>(json, new JsonSerializerSettings
  331. {
  332. TypeNameHandling = TypeNameHandling.Objects,
  333. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  334. });
  335. CustomAssert.IsInstanceOfType(typeof (SendHttpRequest), message);
  336. SendHttpRequest request = (SendHttpRequest) message;
  337. Assert.AreEqual("xyz", request.CorrelationId);
  338. Assert.AreEqual(2, request.RequestData.Count);
  339. Assert.AreEqual("siedemnaście", request.RequestData["Id"]);
  340. }
  341. [Test]
  342. public void SerializeObjectWithMultipleGenericLists()
  343. {
  344. string containerTypeName = typeof (Container).AssemblyQualifiedName;
  345. string productListTypeName = typeof (List<Product>).AssemblyQualifiedName;
  346. Container container = new Container
  347. {
  348. In = new List<Product>(),
  349. Out = new List<Product>()
  350. };
  351. string json = JsonConvert.SerializeObject(container, Formatting.Indented,
  352. new JsonSerializerSettings
  353. {
  354. NullValueHandling = NullValueHandling.Ignore,
  355. TypeNameHandling = TypeNameHandling.All,
  356. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  357. });
  358. Assert.AreEqual(@"{
  359. ""$type"": """ + containerTypeName + @""",
  360. ""In"": {
  361. ""$type"": """ + productListTypeName + @""",
  362. ""$values"": []
  363. },
  364. ""Out"": {
  365. ""$type"": """ + productListTypeName + @""",
  366. ""$values"": []
  367. }
  368. }", json);
  369. }
  370. public class TypeNameProperty
  371. {
  372. public string Name { get; set; }
  373. [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
  374. public object Value { get; set; }
  375. }
  376. [Test]
  377. public void WriteObjectTypeNameForProperty()
  378. {
  379. string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof (TypeNameProperty), FormatterAssemblyStyle.Simple);
  380. TypeNameProperty typeNameProperty = new TypeNameProperty
  381. {
  382. Name = "Name!",
  383. Value = new TypeNameProperty
  384. {
  385. Name = "Nested!"
  386. }
  387. };
  388. string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
  389. Assert.AreEqual(@"{
  390. ""Name"": ""Name!"",
  391. ""Value"": {
  392. ""$type"": """ + typeNamePropertyRef + @""",
  393. ""Name"": ""Nested!"",
  394. ""Value"": null
  395. }
  396. }", json);
  397. TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
  398. Assert.AreEqual("Name!", deserialized.Name);
  399. CustomAssert.IsInstanceOfType(typeof (TypeNameProperty), deserialized.Value);
  400. TypeNameProperty nested = (TypeNameProperty) deserialized.Value;
  401. Assert.AreEqual("Nested!", nested.Name);
  402. Assert.AreEqual(null, nested.Value);
  403. }
  404. [Test]
  405. public void WriteListTypeNameForProperty()
  406. {
  407. string listRef = ReflectionUtils.GetTypeName(typeof (List<int>), FormatterAssemblyStyle.Simple);
  408. TypeNameProperty typeNameProperty = new TypeNameProperty
  409. {
  410. Name = "Name!",
  411. Value = new List<int> {1, 2, 3, 4, 5}
  412. };
  413. string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
  414. Assert.AreEqual(@"{
  415. ""Name"": ""Name!"",
  416. ""Value"": {
  417. ""$type"": """ + listRef + @""",
  418. ""$values"": [
  419. 1,
  420. 2,
  421. 3,
  422. 4,
  423. 5
  424. ]
  425. }
  426. }", json);
  427. TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
  428. Assert.AreEqual("Name!", deserialized.Name);
  429. CustomAssert.IsInstanceOfType(typeof (List<int>), deserialized.Value);
  430. List<int> nested = (List<int>) deserialized.Value;
  431. Assert.AreEqual(5, nested.Count);
  432. Assert.AreEqual(1, nested[0]);
  433. Assert.AreEqual(2, nested[1]);
  434. Assert.AreEqual(3, nested[2]);
  435. Assert.AreEqual(4, nested[3]);
  436. Assert.AreEqual(5, nested[4]);
  437. }
  438. [Test]
  439. public void DeserializeUsingCustomBinder()
  440. {
  441. string json = @"{
  442. ""$id"": ""1"",
  443. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
  444. ""Name"": ""Name!""
  445. }";
  446. object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  447. {
  448. TypeNameHandling = TypeNameHandling.Objects,
  449. Binder = new CustomSerializationBinder()
  450. });
  451. CustomAssert.IsInstanceOfType(typeof (Person), p);
  452. Person person = (Person) p;
  453. Assert.AreEqual("Name!", person.Name);
  454. }
  455. public class CustomSerializationBinder : SerializationBinder
  456. {
  457. public override Type BindToType(string assemblyName, string typeName)
  458. {
  459. return typeof (Person);
  460. }
  461. }
  462. #if !(NET20 || NET35)
  463. [Test]
  464. public void SerializeUsingCustomBinder()
  465. {
  466. TypeNameSerializationBinder binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests");
  467. IList<object> values = new List<object>
  468. {
  469. new Customer
  470. {
  471. Name = "Caroline Customer"
  472. },
  473. new Purchase
  474. {
  475. ProductName = "Elbow Grease",
  476. Price = 5.99m,
  477. Quantity = 1
  478. }
  479. };
  480. string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
  481. {
  482. TypeNameHandling = TypeNameHandling.Auto,
  483. Binder = binder
  484. });
  485. //[
  486. // {
  487. // "$type": "Customer",
  488. // "Name": "Caroline Customer"
  489. // },
  490. // {
  491. // "$type": "Purchase",
  492. // "ProductName": "Elbow Grease",
  493. // "Price": 5.99,
  494. // "Quantity": 1
  495. // }
  496. //]
  497. Assert.AreEqual(@"[
  498. {
  499. ""$type"": ""Customer"",
  500. ""Name"": ""Caroline Customer""
  501. },
  502. {
  503. ""$type"": ""Purchase"",
  504. ""ProductName"": ""Elbow Grease"",
  505. ""Price"": 5.99,
  506. ""Quantity"": 1
  507. }
  508. ]", json);
  509. IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
  510. {
  511. TypeNameHandling = TypeNameHandling.Auto,
  512. Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
  513. });
  514. CustomAssert.IsInstanceOfType(typeof (Customer), newValues[0]);
  515. Customer customer = (Customer) newValues[0];
  516. Assert.AreEqual("Caroline Customer", customer.Name);
  517. CustomAssert.IsInstanceOfType(typeof (Purchase), newValues[1]);
  518. Purchase purchase = (Purchase) newValues[1];
  519. Assert.AreEqual("Elbow Grease", purchase.ProductName);
  520. }
  521. public class TypeNameSerializationBinder : SerializationBinder
  522. {
  523. public string TypeFormat { get; private set; }
  524. public TypeNameSerializationBinder(string typeFormat)
  525. {
  526. TypeFormat = typeFormat;
  527. }
  528. public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
  529. {
  530. assemblyName = null;
  531. typeName = serializedType.Name;
  532. }
  533. public override Type BindToType(string assemblyName, string typeName)
  534. {
  535. string resolvedTypeName = string.Format(TypeFormat, typeName);
  536. return Type.GetType(resolvedTypeName, true);
  537. }
  538. }
  539. #endif
  540. [Test]
  541. public void CollectionWithAbstractItems()
  542. {
  543. HolderClass testObject = new HolderClass();
  544. testObject.TestMember = new ContentSubClass("First One");
  545. testObject.AnotherTestMember = new Dictionary<int, IList<ContentBaseClass>>();
  546. testObject.AnotherTestMember.Add(1, new List<ContentBaseClass>());
  547. testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One"));
  548. testObject.AThirdTestMember = new ContentSubClass("Third One");
  549. JsonSerializer serializingTester = new JsonSerializer();
  550. serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  551. StringWriter sw = new StringWriter();
  552. using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
  553. {
  554. jsonWriter.Formatting = Formatting.Indented;
  555. serializingTester.TypeNameHandling = TypeNameHandling.Auto;
  556. serializingTester.Serialize(jsonWriter, testObject);
  557. }
  558. string json = sw.ToString();
  559. string contentSubClassRef = ReflectionUtils.GetTypeName(typeof (ContentSubClass), FormatterAssemblyStyle.Simple);
  560. string dictionaryRef = ReflectionUtils.GetTypeName(typeof (Dictionary<int, IList<ContentBaseClass>>), FormatterAssemblyStyle.Simple);
  561. string listRef = ReflectionUtils.GetTypeName(typeof (List<ContentBaseClass>), FormatterAssemblyStyle.Simple);
  562. string expected = @"{
  563. ""TestMember"": {
  564. ""$type"": """ + contentSubClassRef + @""",
  565. ""SomeString"": ""First One""
  566. },
  567. ""AnotherTestMember"": {
  568. ""$type"": """ + dictionaryRef + @""",
  569. ""1"": [
  570. {
  571. ""$type"": """ + contentSubClassRef + @""",
  572. ""SomeString"": ""Second One""
  573. }
  574. ]
  575. },
  576. ""AThirdTestMember"": {
  577. ""$type"": """ + contentSubClassRef + @""",
  578. ""SomeString"": ""Third One""
  579. }
  580. }";
  581. Assert.AreEqual(expected, json);
  582. StringReader sr = new StringReader(json);
  583. JsonSerializer deserializingTester = new JsonSerializer();
  584. HolderClass anotherTestObject;
  585. using (JsonTextReader jsonReader = new JsonTextReader(sr))
  586. {
  587. deserializingTester.TypeNameHandling = TypeNameHandling.Auto;
  588. anotherTestObject = deserializingTester.Deserialize<HolderClass>(jsonReader);
  589. }
  590. Assert.IsNotNull(anotherTestObject);
  591. CustomAssert.IsInstanceOfType(typeof (ContentSubClass), anotherTestObject.TestMember);
  592. CustomAssert.IsInstanceOfType(typeof (Dictionary<int, IList<ContentBaseClass>>), anotherTestObject.AnotherTestMember);
  593. Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count);
  594. IList<ContentBaseClass> list = anotherTestObject.AnotherTestMember[1];
  595. CustomAssert.IsInstanceOfType(typeof (List<ContentBaseClass>), list);
  596. Assert.AreEqual(1, list.Count);
  597. CustomAssert.IsInstanceOfType(typeof (ContentSubClass), list[0]);
  598. }
  599. [Test]
  600. public void WriteObjectTypeNameForPropertyDemo()
  601. {
  602. Message message = new Message();
  603. message.Address = "http://www.google.com";
  604. message.Body = new SearchDetails
  605. {
  606. Query = "Json.NET",
  607. Language = "en-us"
  608. };
  609. string json = JsonConvert.SerializeObject(message, Formatting.Indented);
  610. // {
  611. // "Address": "http://www.google.com",
  612. // "Body": {
  613. // "$type": "Newtonsoft.Json.Tests.Serialization.SearchDetails, Newtonsoft.Json.Tests",
  614. // "Query": "Json.NET",
  615. // "Language": "en-us"
  616. // }
  617. // }
  618. Message deserialized = JsonConvert.DeserializeObject<Message>(json);
  619. SearchDetails searchDetails = (SearchDetails) deserialized.Body;
  620. // Json.NET
  621. }
  622. public class UrlStatus
  623. {
  624. public int Status { get; set; }
  625. public string Url { get; set; }
  626. }
  627. [Test]
  628. public void GenericDictionaryObject()
  629. {
  630. Dictionary<string, object> collection = new Dictionary<string, object>()
  631. {
  632. {"First", new UrlStatus {Status = 404, Url = @"http://www.bing.com"}},
  633. {"Second", new UrlStatus {Status = 400, Url = @"http://www.google.com"}},
  634. {
  635. "List", new List<UrlStatus>
  636. {
  637. new UrlStatus {Status = 300, Url = @"http://www.yahoo.com"},
  638. new UrlStatus {Status = 200, Url = @"http://www.askjeeves.com"}
  639. }
  640. }
  641. };
  642. string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
  643. {
  644. TypeNameHandling = TypeNameHandling.All,
  645. TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
  646. });
  647. string urlStatusTypeName = ReflectionUtils.GetTypeName(typeof (UrlStatus), FormatterAssemblyStyle.Simple);
  648. Assert.AreEqual(@"{
  649. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
  650. ""First"": {
  651. ""$type"": """ + urlStatusTypeName + @""",
  652. ""Status"": 404,
  653. ""Url"": ""http://www.bing.com""
  654. },
  655. ""Second"": {
  656. ""$type"": """ + urlStatusTypeName + @""",
  657. ""Status"": 400,
  658. ""Url"": ""http://www.google.com""
  659. },
  660. ""List"": {
  661. ""$type"": ""System.Collections.Generic.List`1[[" + urlStatusTypeName + @"]], mscorlib"",
  662. ""$values"": [
  663. {
  664. ""$type"": """ + urlStatusTypeName + @""",
  665. ""Status"": 300,
  666. ""Url"": ""http://www.yahoo.com""
  667. },
  668. {
  669. ""$type"": """ + urlStatusTypeName + @""",
  670. ""Status"": 200,
  671. ""Url"": ""http://www.askjeeves.com""
  672. }
  673. ]
  674. }
  675. }", json);
  676. object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
  677. {
  678. TypeNameHandling = TypeNameHandling.All,
  679. TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
  680. });
  681. CustomAssert.IsInstanceOfType(typeof (Dictionary<string, object>), c);
  682. Dictionary<string, object> newCollection = (Dictionary<string, object>) c;
  683. Assert.AreEqual(3, newCollection.Count);
  684. Assert.AreEqual(@"http://www.bing.com", ((UrlStatus) newCollection["First"]).Url);
  685. List<UrlStatus> statues = (List<UrlStatus>) newCollection["List"];
  686. Assert.AreEqual(2, statues.Count);
  687. }
  688. [Test]
  689. public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo()
  690. {
  691. string productClassRef = ReflectionUtils.GetTypeName(typeof (Product[]), FormatterAssemblyStyle.Simple);
  692. CustomEnumerable<Product> products = new CustomEnumerable<Product>();
  693. string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All});
  694. Assert.AreEqual(@"{
  695. ""$type"": """ + productClassRef + @""",
  696. ""$values"": []
  697. }", json);
  698. }
  699. public class CustomEnumerable<T> : IEnumerable<T>
  700. {
  701. //NOTE: a simple linked list
  702. private readonly T value;
  703. private readonly CustomEnumerable<T> next;
  704. private readonly int count;
  705. private CustomEnumerable(T value, CustomEnumerable<T> next)
  706. {
  707. this.value = value;
  708. this.next = next;
  709. count = this.next.count + 1;
  710. }
  711. public CustomEnumerable()
  712. {
  713. count = 0;
  714. }
  715. public CustomEnumerable<T> AddFirst(T newVal)
  716. {
  717. return new CustomEnumerable<T>(newVal, this);
  718. }
  719. public IEnumerator<T> GetEnumerator()
  720. {
  721. if (count == 0) // last node
  722. yield break;
  723. yield return value;
  724. var nextInLine = next;
  725. while (nextInLine != null)
  726. {
  727. if (nextInLine.count != 0)
  728. yield return nextInLine.value;
  729. nextInLine = nextInLine.next;
  730. }
  731. }
  732. IEnumerator IEnumerable.GetEnumerator()
  733. {
  734. return GetEnumerator();
  735. }
  736. }
  737. public class Car
  738. {
  739. // included in JSON
  740. public string Model { get; set; }
  741. public DateTime Year { get; set; }
  742. public List<string> Features { get; set; }
  743. public object[] Objects { get; set; }
  744. // ignored
  745. [JsonIgnore]
  746. public DateTime LastModified { get; set; }
  747. }
  748. [Test]
  749. public void ByteArrays()
  750. {
  751. Car testerObject = new Car();
  752. testerObject.Year = new DateTime(2000, 10, 5, 1, 1, 1, DateTimeKind.Utc);
  753. byte[] data = new byte[] {75, 65, 82, 73, 82, 65};
  754. testerObject.Objects = new object[] {data, "prueba"};
  755. JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
  756. jsonSettings.NullValueHandling = NullValueHandling.Ignore;
  757. jsonSettings.TypeNameHandling = TypeNameHandling.All;
  758. string output = JsonConvert.SerializeObject(testerObject, Formatting.Indented, jsonSettings);
  759. string carClassRef = ReflectionUtils.GetTypeName(typeof (Car), FormatterAssemblyStyle.Simple);
  760. Assert.AreEqual(output, @"{
  761. ""$type"": """ + carClassRef + @""",
  762. ""Year"": ""2000-10-05T01:01:01Z"",
  763. ""Objects"": {
  764. ""$type"": ""System.Object[], mscorlib"",
  765. ""$values"": [
  766. {
  767. ""$type"": ""System.Byte[], mscorlib"",
  768. ""$value"": ""S0FSSVJB""
  769. },
  770. ""prueba""
  771. ]
  772. }
  773. }");
  774. Car obj = JsonConvert.DeserializeObject<Car>(output, jsonSettings);
  775. Assert.IsNotNull(obj);
  776. Assert.IsTrue(obj.Objects[0] is byte[]);
  777. byte[] d = (byte[]) obj.Objects[0];
  778. CollectionAssert.AreEquivalent(data, d);
  779. }
  780. #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE)
  781. [Test]
  782. public void ISerializableTypeNameHandlingTest()
  783. {
  784. //Create an instance of our example type
  785. IExample e = new Example("Rob");
  786. SerializableWrapper w = new SerializableWrapper
  787. {
  788. Content = e
  789. };
  790. //Test Binary Serialization Round Trip
  791. //This will work find because the Binary Formatter serializes type names
  792. //this.TestBinarySerializationRoundTrip(e);
  793. //Test Json Serialization
  794. //This fails because the JsonSerializer doesn't serialize type names correctly for ISerializable objects
  795. //Type Names should be serialized for All, Auto and Object modes
  796. this.TestJsonSerializationRoundTrip(w, TypeNameHandling.All);
  797. this.TestJsonSerializationRoundTrip(w, TypeNameHandling.Auto);
  798. this.TestJsonSerializationRoundTrip(w, TypeNameHandling.Objects);
  799. }
  800. private void TestJsonSerializationRoundTrip(SerializableWrapper e, TypeNameHandling flag)
  801. {
  802. Console.WriteLine("Type Name Handling: " + flag.ToString());
  803. StringWriter writer = new StringWriter();
  804. //Create our serializer and set Type Name Handling appropriately
  805. JsonSerializer serializer = new JsonSerializer();
  806. serializer.TypeNameHandling = flag;
  807. //Do the actual serialization and dump to Console for inspection
  808. serializer.Serialize(new JsonTextWriter(writer), e);
  809. Console.WriteLine(writer.ToString());
  810. Console.WriteLine();
  811. //Now try to deserialize
  812. //Json.Net will cause an error here as it will try and instantiate
  813. //the interface directly because it failed to respect the
  814. //TypeNameHandling property on serialization
  815. SerializableWrapper f = serializer.Deserialize<SerializableWrapper>(new JsonTextReader(new StringReader(writer.ToString())));
  816. //Check Round Trip
  817. Assert.AreEqual(e, f, "Objects should be equal after round trip json serialization");
  818. }
  819. #endif
  820. #if !(NET20 || NET35)
  821. [Test]
  822. public void SerializationBinderWithFullName()
  823. {
  824. Message message = new Message
  825. {
  826. Address = "jamesnk@testtown.com",
  827. Body = new Version(1, 2, 3, 4)
  828. };
  829. string json = JsonConvert.SerializeObject(message, Formatting.Indented, new JsonSerializerSettings
  830. {
  831. TypeNameHandling = TypeNameHandling.All,
  832. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
  833. Binder = new MetroBinder(),
  834. ContractResolver = new DefaultContractResolver
  835. {
  836. #if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
  837. IgnoreSerializableAttribute = true
  838. #endif
  839. }
  840. });
  841. Assert.AreEqual(@"{
  842. ""$type"": "":::MESSAGE:::, AssemblyName"",
  843. ""Address"": ""jamesnk@testtown.com"",
  844. ""Body"": {
  845. ""$type"": "":::VERSION:::, AssemblyName"",
  846. ""Major"": 1,
  847. ""Minor"": 2,
  848. ""Build"": 3,
  849. ""Revision"": 4,
  850. ""MajorRevision"": 0,
  851. ""MinorRevision"": 4
  852. }
  853. }", json);
  854. }
  855. public class MetroBinder : SerializationBinder
  856. {
  857. public override Type BindToType(string assemblyName, string typeName)
  858. {
  859. return null;
  860. }
  861. public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
  862. {
  863. assemblyName = "AssemblyName";
  864. #if !NETFX_CORE
  865. typeName = ":::" + serializedType.Name.ToUpper(CultureInfo.InvariantCulture) + ":::";
  866. #else
  867. typeName = ":::" + serializedType.Name.ToUpper() + ":::";
  868. #endif
  869. }
  870. }
  871. #endif
  872. [Test]
  873. public void TypeNameIntList()
  874. {
  875. TypeNameList<int> l = new TypeNameList<int>();
  876. l.Add(1);
  877. l.Add(2);
  878. l.Add(3);
  879. string json = JsonConvert.SerializeObject(l, Formatting.Indented);
  880. Assert.AreEqual(@"[
  881. 1,
  882. 2,
  883. 3
  884. ]", json);
  885. }
  886. [Test]
  887. public void TypeNameComponentList()
  888. {
  889. var c1 = new TestComponentSimple();
  890. TypeNameList<object> l = new TypeNameList<object>();
  891. l.Add(c1);
  892. l.Add(new Employee
  893. {
  894. BirthDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc),
  895. Department = "Department!"
  896. });
  897. l.Add("String!");
  898. l.Add(long.MaxValue);
  899. string json = JsonConvert.SerializeObject(l, Formatting.Indented);
  900. Assert.AreEqual(@"[
  901. {
  902. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  903. ""MyProperty"": 0
  904. },
  905. {
  906. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee, Newtonsoft.Json.Tests"",
  907. ""FirstName"": null,
  908. ""LastName"": null,
  909. ""BirthDate"": ""2000-12-12T12:12:12Z"",
  910. ""Department"": ""Department!"",
  911. ""JobTitle"": null
  912. },
  913. ""String!"",
  914. 9223372036854775807
  915. ]", json);
  916. TypeNameList<object> l2 = JsonConvert.DeserializeObject<TypeNameList<object>>(json);
  917. Assert.AreEqual(4, l2.Count);
  918. CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), l2[0]);
  919. CustomAssert.IsInstanceOfType(typeof (Employee), l2[1]);
  920. CustomAssert.IsInstanceOfType(typeof (string), l2[2]);
  921. CustomAssert.IsInstanceOfType(typeof (long), l2[3]);
  922. }
  923. [Test]
  924. public void TypeNameDictionary()
  925. {
  926. TypeNameDictionary<object> l = new TypeNameDictionary<object>();
  927. l.Add("First", new TestComponentSimple {MyProperty = 1});
  928. l.Add("Second", "String!");
  929. l.Add("Third", long.MaxValue);
  930. string json = JsonConvert.SerializeObject(l, Formatting.Indented);
  931. Assert.AreEqual(@"{
  932. ""First"": {
  933. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  934. ""MyProperty"": 1
  935. },
  936. ""Second"": ""String!"",
  937. ""Third"": 9223372036854775807
  938. }", json);
  939. TypeNameDictionary<object> l2 = JsonConvert.DeserializeObject<TypeNameDictionary<object>>(json);
  940. Assert.AreEqual(3, l2.Count);
  941. CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), l2["First"]);
  942. Assert.AreEqual(1, ((TestComponentSimple) l2["First"]).MyProperty);
  943. CustomAssert.IsInstanceOfType(typeof (string), l2["Second"]);
  944. CustomAssert.IsInstanceOfType(typeof (long), l2["Third"]);
  945. }
  946. [Test]
  947. public void TypeNameObjectItems()
  948. {
  949. TypeNameObject o1 = new TypeNameObject();
  950. o1.Object1 = new TestComponentSimple {MyProperty = 1};
  951. o1.Object2 = 123;
  952. o1.ObjectNotHandled = new TestComponentSimple {MyProperty = int.MaxValue};
  953. o1.String = "String!";
  954. o1.Integer = int.MaxValue;
  955. string json = JsonConvert.SerializeObject(o1, Formatting.Indented);
  956. string expected = @"{
  957. ""Object1"": {
  958. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  959. ""MyProperty"": 1
  960. },
  961. ""Object2"": 123,
  962. ""ObjectNotHandled"": {
  963. ""MyProperty"": 2147483647
  964. },
  965. ""String"": ""String!"",
  966. ""Integer"": 2147483647
  967. }";
  968. Assert.AreEqual(expected, json);
  969. TypeNameObject o2 = JsonConvert.DeserializeObject<TypeNameObject>(json);
  970. Assert.IsNotNull(o2);
  971. CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), o2.Object1);
  972. Assert.AreEqual(1, ((TestComponentSimple) o2.Object1).MyProperty);
  973. CustomAssert.IsInstanceOfType(typeof (long), o2.Object2);
  974. CustomAssert.IsInstanceOfType(typeof (JObject), o2.ObjectNotHandled);
  975. Assert.AreEqual(@"{
  976. ""MyProperty"": 2147483647
  977. }", o2.ObjectNotHandled.ToString());
  978. }
  979. [Test]
  980. public void PropertyItemTypeNameHandling()
  981. {
  982. PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling();
  983. c1.Data = new List<object>
  984. {
  985. 1,
  986. "two",
  987. new TestComponentSimple {MyProperty = 1}
  988. };
  989. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  990. Assert.AreEqual(@"{
  991. ""Data"": [
  992. 1,
  993. ""two"",
  994. {
  995. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  996. ""MyProperty"": 1
  997. }
  998. ]
  999. }", json);
  1000. PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
  1001. Assert.AreEqual(3, c2.Data.Count);
  1002. CustomAssert.IsInstanceOfType(typeof (long), c2.Data[0]);
  1003. CustomAssert.IsInstanceOfType(typeof (string), c2.Data[1]);
  1004. CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[2]);
  1005. TestComponentSimple c = (TestComponentSimple) c2.Data[2];
  1006. Assert.AreEqual(1, c.MyProperty);
  1007. }
  1008. [Test]
  1009. public void PropertyItemTypeNameHandlingNestedCollections()
  1010. {
  1011. PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling
  1012. {
  1013. Data = new List<object>
  1014. {
  1015. new TestComponentSimple {MyProperty = 1},
  1016. new List<object>
  1017. {
  1018. new List<object>
  1019. {
  1020. new List<object>()
  1021. }
  1022. }
  1023. }
  1024. };
  1025. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  1026. Assert.AreEqual(@"{
  1027. ""Data"": [
  1028. {
  1029. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1030. ""MyProperty"": 1
  1031. },
  1032. {
  1033. ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
  1034. ""$values"": [
  1035. [
  1036. []
  1037. ]
  1038. ]
  1039. }
  1040. ]
  1041. }", json);
  1042. PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
  1043. Assert.AreEqual(2, c2.Data.Count);
  1044. CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[0]);
  1045. CustomAssert.IsInstanceOfType(typeof (List<object>), c2.Data[1]);
  1046. List<object> c = (List<object>) c2.Data[1];
  1047. CustomAssert.IsInstanceOfType(typeof (JArray), c[0]);
  1048. json = @"{
  1049. ""Data"": [
  1050. {
  1051. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1052. ""MyProperty"": 1
  1053. },
  1054. {
  1055. ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
  1056. ""$values"": [
  1057. {
  1058. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1059. ""MyProperty"": 1
  1060. }
  1061. ]
  1062. }
  1063. ]
  1064. }";
  1065. c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
  1066. Assert.AreEqual(2, c2.Data.Count);
  1067. CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[0]);
  1068. CustomAssert.IsInstanceOfType(typeof (List<object>), c2.Data[1]);
  1069. c = (List<object>) c2.Data[1];
  1070. CustomAssert.IsInstanceOfType(typeof (JObject), c[0]);
  1071. JObject o = (JObject) c[0];
  1072. Assert.AreEqual(1, (int) o["MyProperty"]);
  1073. }
  1074. [Test]
  1075. public void PropertyItemTypeNameHandlingNestedDictionaries()
  1076. {
  1077. PropertyItemTypeNameHandlingDictionary c1 = new PropertyItemTypeNameHandlingDictionary()
  1078. {
  1079. Data = new Dictionary<string, object>
  1080. {
  1081. {
  1082. "one", new TestComponentSimple {MyProperty = 1}
  1083. },
  1084. {
  1085. "two", new Dictionary<string, object>
  1086. {
  1087. {
  1088. "one", new Dictionary<string, object>
  1089. {
  1090. {"one", 1}
  1091. }
  1092. }
  1093. }
  1094. }
  1095. }
  1096. };
  1097. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  1098. Assert.AreEqual(@"{
  1099. ""Data"": {
  1100. ""one"": {
  1101. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1102. ""MyProperty"": 1
  1103. },
  1104. ""two"": {
  1105. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
  1106. ""one"": {
  1107. ""one"": 1
  1108. }
  1109. }
  1110. }
  1111. }", json);
  1112. PropertyItemTypeNameHandlingDictionary c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDictionary>(json);
  1113. Assert.AreEqual(2, c2.Data.Count);
  1114. CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data["one"]);
  1115. CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c2.Data["two"]);
  1116. Dictionary<string, object> c = (Dictionary<string, object>)c2.Data["two"];
  1117. CustomAssert.IsInstanceOfType(typeof (JObject), c["one"]);
  1118. json = @"{
  1119. ""Data"": {
  1120. ""one"": {
  1121. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1122. ""MyProperty"": 1
  1123. },
  1124. ""two"": {
  1125. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
  1126. ""one"": {
  1127. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1128. ""MyProperty"": 1
  1129. }
  1130. }
  1131. }
  1132. }";
  1133. c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDictionary>(json);
  1134. Assert.AreEqual(2, c2.Data.Count);
  1135. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data["one"]);
  1136. CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c2.Data["two"]);
  1137. c = (Dictionary<string, object>)c2.Data["two"];
  1138. CustomAssert.IsInstanceOfType(typeof(JObject), c["one"]);
  1139. JObject o = (JObject) c["one"];
  1140. Assert.AreEqual(1, (int) o["MyProperty"]);
  1141. }
  1142. [Test]
  1143. public void PropertyItemTypeNameHandlingObject()
  1144. {
  1145. PropertyItemTypeNameHandlingObject o1 = new PropertyItemTypeNameHandlingObject
  1146. {
  1147. Data = new TypeNameHandlingTestObject
  1148. {
  1149. Prop1 = new List<object>
  1150. {
  1151. new TestComponentSimple
  1152. {
  1153. MyProperty = 1
  1154. }
  1155. },
  1156. Prop2 = new TestComponentSimple
  1157. {
  1158. MyProperty = 1
  1159. },
  1160. Prop3 = 3,
  1161. Prop4 = new JObject()
  1162. }
  1163. };
  1164. string json = JsonConvert.SerializeObject(o1, Formatting.Indented);
  1165. Assert.AreEqual(@"{
  1166. ""Data"": {
  1167. ""Prop1"": {
  1168. ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
  1169. ""$values"": [
  1170. {
  1171. ""MyProperty"": 1
  1172. }
  1173. ]
  1174. },
  1175. ""Prop2"": {
  1176. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1177. ""MyProperty"": 1
  1178. },
  1179. ""Prop3"": 3,
  1180. ""Prop4"": {}
  1181. }
  1182. }", json);
  1183. PropertyItemTypeNameHandlingObject o2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingObject>(json);
  1184. Assert.IsNotNull(o2);
  1185. Assert.IsNotNull(o2.Data);
  1186. CustomAssert.IsInstanceOfType(typeof(List<object>), o2.Data.Prop1);
  1187. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), o2.Data.Prop2);
  1188. CustomAssert.IsInstanceOfType(typeof(long), o2.Data.Prop3);
  1189. CustomAssert.IsInstanceOfType(typeof(JObject), o2.Data.Prop4);
  1190. List<object> o = (List<object>)o2.Data.Prop1;
  1191. JObject j = (JObject)o[0];
  1192. Assert.AreEqual(1, (int)j["MyProperty"]);
  1193. }
  1194. #if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
  1195. [Test]
  1196. public void PropertyItemTypeNameHandlingDynamic()
  1197. {
  1198. PropertyItemTypeNameHandlingDynamic d1 = new PropertyItemTypeNameHandlingDynamic();
  1199. dynamic data = new DynamicDictionary();
  1200. data.one = new TestComponentSimple
  1201. {
  1202. MyProperty = 1
  1203. };
  1204. dynamic data2 = new DynamicDictionary();
  1205. data2.one = new TestComponentSimple
  1206. {
  1207. MyProperty = 2
  1208. };
  1209. data.two = data2;
  1210. d1.Data = (DynamicDictionary)data;
  1211. string json = JsonConvert.SerializeObject(d1, Formatting.Indented);
  1212. Assert.AreEqual(@"{
  1213. ""Data"": {
  1214. ""one"": {
  1215. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1216. ""MyProperty"": 1
  1217. },
  1218. ""two"": {
  1219. ""$type"": ""Newtonsoft.Json.Tests.Linq.DynamicDictionary, Newtonsoft.Json.Tests"",
  1220. ""one"": {
  1221. ""MyProperty"": 2
  1222. }
  1223. }
  1224. }
  1225. }", json);
  1226. PropertyItemTypeNameHandlingDynamic d2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDynamic>(json);
  1227. Assert.IsNotNull(d2);
  1228. Assert.IsNotNull(d2.Data);
  1229. dynamic data3 = d2.Data;
  1230. TestComponentSimple c = (TestComponentSimple)data3.one;
  1231. Assert.AreEqual(1, c.MyProperty);
  1232. dynamic data4 = data3.two;
  1233. JObject o = (JObject)data4.one;
  1234. Assert.AreEqual(2, (int)o["MyProperty"]);
  1235. json = @"{
  1236. ""Data"": {
  1237. ""one"": {
  1238. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1239. ""MyProperty"": 1
  1240. },
  1241. ""two"": {
  1242. ""$type"": ""Newtonsoft.Json.Tests.Linq.DynamicDictionary, Newtonsoft.Json.Tests"",
  1243. ""one"": {
  1244. ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"",
  1245. ""MyProperty"": 2
  1246. }
  1247. }
  1248. }
  1249. }";
  1250. d2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDynamic>(json);
  1251. data3 = d2.Data;
  1252. data4 = data3.two;
  1253. o = (JObject)data4.one;
  1254. Assert.AreEqual(2, (int)o["MyProperty"]);
  1255. }
  1256. #endif
  1257. }
  1258. public class Message
  1259. {
  1260. public string Address { get; set; }
  1261. [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
  1262. public object Body { get; set; }
  1263. }
  1264. public class SearchDetails
  1265. {
  1266. public string Query { get; set; }
  1267. public string Language { get; set; }
  1268. }
  1269. public class Customer
  1270. {
  1271. public string Name { get; set; }
  1272. }
  1273. public class Purchase
  1274. {
  1275. public string ProductName { get; set; }
  1276. public decimal Price { get; set; }
  1277. public int Quantity { get; set; }
  1278. }
  1279. #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE)
  1280. public class SerializableWrapper
  1281. {
  1282. public object Content { get; set; }
  1283. public override bool Equals(object obj)
  1284. {
  1285. SerializableWrapper w = obj as SerializableWrapper;
  1286. if (w == null)
  1287. return false;
  1288. return Equals(w.Content, Content);
  1289. }
  1290. }
  1291. public interface IExample
  1292. : ISerializable
  1293. {
  1294. String Name
  1295. {
  1296. get;
  1297. }
  1298. }
  1299. [Serializable]
  1300. public class Example
  1301. : IExample
  1302. {
  1303. public Example(String name)
  1304. {
  1305. this.Name = name;
  1306. }
  1307. protected Example(SerializationInfo info, StreamingContext context)
  1308. {
  1309. this.Name = info.GetString("name");
  1310. }
  1311. public void GetObjectData(SerializationInfo info, StreamingContext context)
  1312. {
  1313. info.AddValue("name", this.Name);
  1314. }
  1315. public String Name { get; set; }
  1316. public override bool Equals(object obj)
  1317. {
  1318. if (obj == null) return false;
  1319. if (ReferenceEquals(this, obj)) return true;
  1320. if (obj is IExample)
  1321. {
  1322. return this.Name.Equals(((IExample)obj).Name);
  1323. }
  1324. else
  1325. {
  1326. return false;
  1327. }
  1328. }
  1329. }
  1330. #endif
  1331. public class PropertyItemTypeNameHandlingObject
  1332. {
  1333. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  1334. public TypeNameHandlingTestObject Data { get; set; }
  1335. }
  1336. #if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE)
  1337. public class PropertyItemTypeNameHandlingDynamic
  1338. {
  1339. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  1340. public DynamicDictionary Data { get; set; }
  1341. }
  1342. #endif
  1343. public class TypeNameHandlingTestObject
  1344. {
  1345. public object Prop1 { get; set; }
  1346. public object Prop2 { get; set; }
  1347. public object Prop3 { get; set; }
  1348. public object Prop4 { get; set; }
  1349. }
  1350. public class PropertyItemTypeNameHandlingDictionary
  1351. {
  1352. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  1353. public IDictionary<string, object> Data { get; set; }
  1354. }
  1355. public class PropertyItemTypeNameHandling
  1356. {
  1357. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  1358. public IList<object> Data { get; set; }
  1359. }
  1360. [JsonArray(ItemTypeNameHandling = TypeNameHandling.All)]
  1361. public class TypeNameList<T> : List<T>
  1362. {
  1363. }
  1364. [JsonDictionary(ItemTypeNameHandling = TypeNameHandling.All)]
  1365. public class TypeNameDictionary<T> : Dictionary<string, T>
  1366. {
  1367. }
  1368. [JsonObject(ItemTypeNameHandling = TypeNameHandling.All)]
  1369. public class TypeNameObject
  1370. {
  1371. public object Object1 { get; set; }
  1372. public object Object2 { get; set; }
  1373. [JsonProperty(TypeNameHandling = TypeNameHandling.None)]
  1374. public object ObjectNotHandled { get; set; }
  1375. public string String { get; set; }
  1376. public int Integer { get; set; }
  1377. }
  1378. }
  1379. #endif