PageRenderTime 46ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/wfpcoslv/maps-examples
C# | 2489 lines | 2440 code | 18 blank | 31 comment | 3 complexity | 4c4d27df53656e92ea12e479ecf4084c MD5 | raw file
Possible License(s): GPL-2.0
  1. #region License
  2. // Copyright (c) 2007 James Newton-King
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. #endregion
  25. #if NET20
  26. using Newtonsoft.Json.Utilities.LinqBridge;
  27. #else
  28. using System.Linq;
  29. #endif
  30. #if !(PORTABLE || PORTABLE40)
  31. using System.Collections.ObjectModel;
  32. #if !(NET35 || NET20)
  33. using System.Dynamic;
  34. #endif
  35. using System.Text;
  36. using Newtonsoft.Json.Tests.Linq;
  37. using System;
  38. using System.Collections;
  39. using System.Collections.Generic;
  40. using System.Globalization;
  41. using System.Runtime.Serialization.Formatters;
  42. using Newtonsoft.Json.Linq;
  43. using Newtonsoft.Json.Serialization;
  44. using Newtonsoft.Json.Tests.TestObjects;
  45. using Newtonsoft.Json.Tests.TestObjects.Organization;
  46. #if DNXCORE50
  47. using Xunit;
  48. using Test = Xunit.FactAttribute;
  49. using Assert = Newtonsoft.Json.Tests.XUnitAssert;
  50. #else
  51. using NUnit.Framework;
  52. #endif
  53. using Newtonsoft.Json.Utilities;
  54. using System.Net;
  55. using System.Runtime.Serialization;
  56. using System.IO;
  57. using System.Reflection;
  58. namespace Newtonsoft.Json.Tests.Serialization
  59. {
  60. [TestFixture]
  61. public class TypeNameHandlingTests : TestFixtureBase
  62. {
  63. #if !(NET20 || NET35)
  64. [Test]
  65. public void SerializeValueTupleWithTypeName()
  66. {
  67. string tupleRef = ReflectionUtils.GetTypeName(typeof(ValueTuple<int, int, string>), TypeNameAssemblyFormatHandling.Simple, null);
  68. ValueTuple<int, int, string> t = ValueTuple.Create(1, 2, "string");
  69. string json = JsonConvert.SerializeObject(t, Formatting.Indented, new JsonSerializerSettings
  70. {
  71. TypeNameHandling = TypeNameHandling.All
  72. });
  73. StringAssert.AreEqual(@"{
  74. ""$type"": """ + tupleRef + @""",
  75. ""Item1"": 1,
  76. ""Item2"": 2,
  77. ""Item3"": ""string""
  78. }", json);
  79. ValueTuple<int, int, string> t2 = (ValueTuple<int, int, string>)JsonConvert.DeserializeObject(json, new JsonSerializerSettings
  80. {
  81. TypeNameHandling = TypeNameHandling.All
  82. });
  83. Assert.AreEqual(1, t2.Item1);
  84. Assert.AreEqual(2, t2.Item2);
  85. Assert.AreEqual("string", t2.Item3);
  86. }
  87. #endif
  88. #if !(NET20 || NET35 || NET40)
  89. public class KnownAutoTypes
  90. {
  91. public ICollection<string> Collection { get; set; }
  92. public IList<string> List { get; set; }
  93. public IDictionary<string, string> Dictionary { get; set; }
  94. public ISet<string> Set { get; set; }
  95. public IReadOnlyCollection<string> ReadOnlyCollection { get; set; }
  96. public IReadOnlyList<string> ReadOnlyList { get; set; }
  97. public IReadOnlyDictionary<string, string> ReadOnlyDictionary { get; set; }
  98. }
  99. [Test]
  100. public void KnownAutoTypesTest()
  101. {
  102. KnownAutoTypes c = new KnownAutoTypes
  103. {
  104. Collection = new List<string> { "Collection value!" },
  105. List = new List<string> { "List value!" },
  106. Dictionary = new Dictionary<string, string>
  107. {
  108. { "Dictionary key!", "Dictionary value!" }
  109. },
  110. ReadOnlyCollection = new ReadOnlyCollection<string>(new[] { "Read Only Collection value!" }),
  111. ReadOnlyList = new ReadOnlyCollection<string>(new[] { "Read Only List value!" }),
  112. Set = new HashSet<string> { "Set value!" },
  113. ReadOnlyDictionary = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>
  114. {
  115. { "Read Only Dictionary key!", "Read Only Dictionary value!" }
  116. })
  117. };
  118. string json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings
  119. {
  120. TypeNameHandling = TypeNameHandling.Auto
  121. });
  122. StringAssert.AreEqual(@"{
  123. ""Collection"": [
  124. ""Collection value!""
  125. ],
  126. ""List"": [
  127. ""List value!""
  128. ],
  129. ""Dictionary"": {
  130. ""Dictionary key!"": ""Dictionary value!""
  131. },
  132. ""Set"": [
  133. ""Set value!""
  134. ],
  135. ""ReadOnlyCollection"": [
  136. ""Read Only Collection value!""
  137. ],
  138. ""ReadOnlyList"": [
  139. ""Read Only List value!""
  140. ],
  141. ""ReadOnlyDictionary"": {
  142. ""Read Only Dictionary key!"": ""Read Only Dictionary value!""
  143. }
  144. }", json);
  145. }
  146. #endif
  147. [Test]
  148. public void DictionaryAuto()
  149. {
  150. Dictionary<string, object> dic = new Dictionary<string, object>
  151. {
  152. { "movie", new Movie { Name = "Die Hard" } }
  153. };
  154. string json = JsonConvert.SerializeObject(dic, Formatting.Indented, new JsonSerializerSettings
  155. {
  156. TypeNameHandling = TypeNameHandling.Auto
  157. });
  158. StringAssert.AreEqual(@"{
  159. ""movie"": {
  160. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Movie, Newtonsoft.Json.Tests"",
  161. ""Name"": ""Die Hard"",
  162. ""Description"": null,
  163. ""Classification"": null,
  164. ""Studio"": null,
  165. ""ReleaseDate"": null,
  166. ""ReleaseCountries"": null
  167. }
  168. }", json);
  169. }
  170. [Test]
  171. public void KeyValuePairAuto()
  172. {
  173. IList<KeyValuePair<string, object>> dic = new List<KeyValuePair<string, object>>
  174. {
  175. new KeyValuePair<string, object>("movie", new Movie { Name = "Die Hard" })
  176. };
  177. string json = JsonConvert.SerializeObject(dic, Formatting.Indented, new JsonSerializerSettings
  178. {
  179. TypeNameHandling = TypeNameHandling.Auto
  180. });
  181. StringAssert.AreEqual(@"[
  182. {
  183. ""Key"": ""movie"",
  184. ""Value"": {
  185. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Movie, Newtonsoft.Json.Tests"",
  186. ""Name"": ""Die Hard"",
  187. ""Description"": null,
  188. ""Classification"": null,
  189. ""Studio"": null,
  190. ""ReleaseDate"": null,
  191. ""ReleaseCountries"": null
  192. }
  193. }
  194. ]", json);
  195. }
  196. [Test]
  197. public void NestedValueObjects()
  198. {
  199. StringBuilder sb = new StringBuilder();
  200. for (int i = 0; i < 3; i++)
  201. {
  202. sb.Append(@"{""$value"":");
  203. }
  204. ExceptionAssert.Throws<JsonSerializationException>(() =>
  205. {
  206. var reader = new JsonTextReader(new StringReader(sb.ToString()));
  207. var ser = new JsonSerializer();
  208. ser.MetadataPropertyHandling = MetadataPropertyHandling.Default;
  209. ser.Deserialize<sbyte>(reader);
  210. }, "Unexpected token when deserializing primitive value: StartObject. Path '$value', line 1, position 11.");
  211. }
  212. [Test]
  213. public void SerializeRootTypeNameIfDerivedWithAuto()
  214. {
  215. var serializer = new JsonSerializer()
  216. {
  217. TypeNameHandling = TypeNameHandling.Auto
  218. };
  219. var sw = new StringWriter();
  220. serializer.Serialize(new JsonTextWriter(sw) { Formatting = Formatting.Indented }, new WagePerson(), typeof(Person));
  221. var result = sw.ToString();
  222. StringAssert.AreEqual(@"{
  223. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",
  224. ""HourlyWage"": 0.0,
  225. ""Name"": null,
  226. ""BirthDate"": ""0001-01-01T00:00:00"",
  227. ""LastModified"": ""0001-01-01T00:00:00""
  228. }", result);
  229. Assert.IsTrue(result.Contains("WagePerson"));
  230. using (var rd = new JsonTextReader(new StringReader(result)))
  231. {
  232. var person = serializer.Deserialize<Person>(rd);
  233. CustomAssert.IsInstanceOfType(typeof(WagePerson), person);
  234. }
  235. }
  236. [Test]
  237. public void SerializeRootTypeNameAutoWithJsonConvert()
  238. {
  239. string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), Formatting.Indented, new JsonSerializerSettings
  240. {
  241. TypeNameHandling = TypeNameHandling.Auto
  242. });
  243. StringAssert.AreEqual(@"{
  244. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",
  245. ""HourlyWage"": 0.0,
  246. ""Name"": null,
  247. ""BirthDate"": ""0001-01-01T00:00:00"",
  248. ""LastModified"": ""0001-01-01T00:00:00""
  249. }", json);
  250. }
  251. [Test]
  252. public void SerializeRootTypeNameAutoWithJsonConvert_Generic()
  253. {
  254. string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), Formatting.Indented, new JsonSerializerSettings
  255. {
  256. TypeNameHandling = TypeNameHandling.Auto
  257. });
  258. StringAssert.AreEqual(@"{
  259. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",
  260. ""HourlyWage"": 0.0,
  261. ""Name"": null,
  262. ""BirthDate"": ""0001-01-01T00:00:00"",
  263. ""LastModified"": ""0001-01-01T00:00:00""
  264. }", json);
  265. }
  266. [Test]
  267. public void SerializeRootTypeNameAutoWithJsonConvert_Generic2()
  268. {
  269. string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), new JsonSerializerSettings
  270. {
  271. TypeNameHandling = TypeNameHandling.Auto
  272. });
  273. StringAssert.AreEqual(@"{""$type"":""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",""HourlyWage"":0.0,""Name"":null,""BirthDate"":""0001-01-01T00:00:00"",""LastModified"":""0001-01-01T00:00:00""}", json);
  274. }
  275. public class Wrapper
  276. {
  277. public IList<EmployeeReference> Array { get; set; }
  278. public IDictionary<string, EmployeeReference> Dictionary { get; set; }
  279. }
  280. [Test]
  281. public void SerializeWrapper()
  282. {
  283. Wrapper wrapper = new Wrapper();
  284. wrapper.Array = new List<EmployeeReference>
  285. {
  286. new EmployeeReference()
  287. };
  288. wrapper.Dictionary = new Dictionary<string, EmployeeReference>
  289. {
  290. { "First", new EmployeeReference() }
  291. };
  292. string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented, new JsonSerializerSettings
  293. {
  294. TypeNameHandling = TypeNameHandling.Auto
  295. });
  296. StringAssert.AreEqual(@"{
  297. ""Array"": [
  298. {
  299. ""$id"": ""1"",
  300. ""Name"": null,
  301. ""Manager"": null
  302. }
  303. ],
  304. ""Dictionary"": {
  305. ""First"": {
  306. ""$id"": ""2"",
  307. ""Name"": null,
  308. ""Manager"": null
  309. }
  310. }
  311. }", json);
  312. Wrapper w2 = JsonConvert.DeserializeObject<Wrapper>(json);
  313. CustomAssert.IsInstanceOfType(typeof(List<EmployeeReference>), w2.Array);
  314. CustomAssert.IsInstanceOfType(typeof(Dictionary<string, EmployeeReference>), w2.Dictionary);
  315. }
  316. [Test]
  317. public void WriteTypeNameForObjects()
  318. {
  319. string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), TypeNameAssemblyFormatHandling.Simple, null);
  320. EmployeeReference employee = new EmployeeReference();
  321. string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings
  322. {
  323. TypeNameHandling = TypeNameHandling.Objects
  324. });
  325. StringAssert.AreEqual(@"{
  326. ""$id"": ""1"",
  327. ""$type"": """ + employeeRef + @""",
  328. ""Name"": null,
  329. ""Manager"": null
  330. }", json);
  331. }
  332. [Test]
  333. public void DeserializeTypeName()
  334. {
  335. string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), TypeNameAssemblyFormatHandling.Simple, null);
  336. string json = @"{
  337. ""$id"": ""1"",
  338. ""$type"": """ + employeeRef + @""",
  339. ""Name"": ""Name!"",
  340. ""Manager"": null
  341. }";
  342. object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  343. {
  344. TypeNameHandling = TypeNameHandling.Objects
  345. });
  346. CustomAssert.IsInstanceOfType(typeof(EmployeeReference), employee);
  347. Assert.AreEqual("Name!", ((EmployeeReference)employee).Name);
  348. }
  349. #if !(PORTABLE || DNXCORE50)
  350. [Test]
  351. public void DeserializeTypeNameFromGacAssembly()
  352. {
  353. string cookieRef = ReflectionUtils.GetTypeName(typeof(Cookie), TypeNameAssemblyFormatHandling.Simple, null);
  354. string json = @"{
  355. ""$id"": ""1"",
  356. ""$type"": """ + cookieRef + @"""
  357. }";
  358. object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  359. {
  360. TypeNameHandling = TypeNameHandling.Objects
  361. });
  362. CustomAssert.IsInstanceOfType(typeof(Cookie), cookie);
  363. }
  364. #endif
  365. [Test]
  366. public void SerializeGenericObjectListWithTypeName()
  367. {
  368. string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
  369. string personRef = typeof(Person).AssemblyQualifiedName;
  370. List<object> values = new List<object>
  371. {
  372. new EmployeeReference
  373. {
  374. Name = "Bob",
  375. Manager = new EmployeeReference { Name = "Frank" }
  376. },
  377. new Person
  378. {
  379. Department = "Department",
  380. BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc),
  381. LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc)
  382. },
  383. "String!",
  384. int.MinValue
  385. };
  386. string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
  387. {
  388. TypeNameHandling = TypeNameHandling.Objects,
  389. #pragma warning disable 618
  390. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  391. #pragma warning restore 618
  392. });
  393. StringAssert.AreEqual(@"[
  394. {
  395. ""$id"": ""1"",
  396. ""$type"": """ + employeeRef + @""",
  397. ""Name"": ""Bob"",
  398. ""Manager"": {
  399. ""$id"": ""2"",
  400. ""$type"": """ + employeeRef + @""",
  401. ""Name"": ""Frank"",
  402. ""Manager"": null
  403. }
  404. },
  405. {
  406. ""$type"": """ + personRef + @""",
  407. ""Name"": null,
  408. ""BirthDate"": ""2000-12-30T00:00:00Z"",
  409. ""LastModified"": ""2000-12-30T00:00:00Z""
  410. },
  411. ""String!"",
  412. -2147483648
  413. ]", json);
  414. }
  415. [Test]
  416. public void DeserializeGenericObjectListWithTypeName()
  417. {
  418. string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
  419. string personRef = typeof(Person).AssemblyQualifiedName;
  420. string json = @"[
  421. {
  422. ""$id"": ""1"",
  423. ""$type"": """ + employeeRef + @""",
  424. ""Name"": ""Bob"",
  425. ""Manager"": {
  426. ""$id"": ""2"",
  427. ""$type"": """ + employeeRef + @""",
  428. ""Name"": ""Frank"",
  429. ""Manager"": null
  430. }
  431. },
  432. {
  433. ""$type"": """ + personRef + @""",
  434. ""Name"": null,
  435. ""BirthDate"": ""\/Date(978134400000)\/"",
  436. ""LastModified"": ""\/Date(978134400000)\/""
  437. },
  438. ""String!"",
  439. -2147483648
  440. ]";
  441. List<object> values = (List<object>)JsonConvert.DeserializeObject(json, typeof(List<object>), new JsonSerializerSettings
  442. {
  443. TypeNameHandling = TypeNameHandling.Objects,
  444. #pragma warning disable 618
  445. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  446. #pragma warning restore 618
  447. });
  448. Assert.AreEqual(4, values.Count);
  449. EmployeeReference e = (EmployeeReference)values[0];
  450. Person p = (Person)values[1];
  451. Assert.AreEqual("Bob", e.Name);
  452. Assert.AreEqual("Frank", e.Manager.Name);
  453. Assert.AreEqual(null, p.Name);
  454. Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate);
  455. Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified);
  456. Assert.AreEqual("String!", values[2]);
  457. Assert.AreEqual((long)int.MinValue, values[3]);
  458. }
  459. [Test]
  460. public void DeserializeWithBadTypeName()
  461. {
  462. string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
  463. string personRef = typeof(Person).AssemblyQualifiedName;
  464. string json = @"{
  465. ""$id"": ""1"",
  466. ""$type"": """ + employeeRef + @""",
  467. ""Name"": ""Name!"",
  468. ""Manager"": null
  469. }";
  470. try
  471. {
  472. JsonConvert.DeserializeObject(json, typeof(Person), new JsonSerializerSettings
  473. {
  474. TypeNameHandling = TypeNameHandling.Objects,
  475. #pragma warning disable 618
  476. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  477. #pragma warning restore 618
  478. });
  479. }
  480. catch (JsonSerializationException ex)
  481. {
  482. Assert.IsTrue(ex.Message.StartsWith(@"Type specified in JSON '" + employeeRef + @"' is not compatible with '" + personRef + @"'."));
  483. }
  484. }
  485. [Test]
  486. public void DeserializeTypeNameWithNoTypeNameHandling()
  487. {
  488. string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
  489. string json = @"{
  490. ""$id"": ""1"",
  491. ""$type"": """ + employeeRef + @""",
  492. ""Name"": ""Name!"",
  493. ""Manager"": null
  494. }";
  495. JObject o = (JObject)JsonConvert.DeserializeObject(json);
  496. StringAssert.AreEqual(@"{
  497. ""Name"": ""Name!"",
  498. ""Manager"": null
  499. }", o.ToString());
  500. }
  501. [Test]
  502. public void DeserializeTypeNameOnly()
  503. {
  504. string json = @"{
  505. ""$id"": ""1"",
  506. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
  507. ""Name"": ""Name!"",
  508. ""Manager"": null
  509. }";
  510. ExceptionAssert.Throws<JsonSerializationException>(() =>
  511. {
  512. JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  513. {
  514. TypeNameHandling = TypeNameHandling.Objects
  515. });
  516. }, "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved. Path '$type', line 3, position 55.");
  517. }
  518. public interface ICorrelatedMessage
  519. {
  520. string CorrelationId { get; set; }
  521. }
  522. public class SendHttpRequest : ICorrelatedMessage
  523. {
  524. public SendHttpRequest()
  525. {
  526. RequestEncoding = "UTF-8";
  527. Method = "GET";
  528. }
  529. public string Method { get; set; }
  530. public Dictionary<string, string> Headers { get; set; }
  531. public string Url { get; set; }
  532. public Dictionary<string, string> RequestData;
  533. public string RequestBodyText { get; set; }
  534. public string User { get; set; }
  535. public string Passwd { get; set; }
  536. public string RequestEncoding { get; set; }
  537. public string CorrelationId { get; set; }
  538. }
  539. [Test]
  540. public void DeserializeGenericTypeName()
  541. {
  542. string typeName = typeof(SendHttpRequest).AssemblyQualifiedName;
  543. string json = @"{
  544. ""$type"": """ + typeName + @""",
  545. ""RequestData"": {
  546. ""$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"",
  547. ""Id"": ""siedemnaście"",
  548. ""X"": ""323""
  549. },
  550. ""Method"": ""GET"",
  551. ""Url"": ""http://www.onet.pl"",
  552. ""RequestEncoding"": ""UTF-8"",
  553. ""CorrelationId"": ""xyz""
  554. }";
  555. ICorrelatedMessage message = JsonConvert.DeserializeObject<ICorrelatedMessage>(json, new JsonSerializerSettings
  556. {
  557. TypeNameHandling = TypeNameHandling.Objects,
  558. #pragma warning disable 618
  559. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  560. #pragma warning restore 618
  561. });
  562. CustomAssert.IsInstanceOfType(typeof(SendHttpRequest), message);
  563. SendHttpRequest request = (SendHttpRequest)message;
  564. Assert.AreEqual("xyz", request.CorrelationId);
  565. Assert.AreEqual(2, request.RequestData.Count);
  566. Assert.AreEqual("siedemnaście", request.RequestData["Id"]);
  567. }
  568. [Test]
  569. public void SerializeObjectWithMultipleGenericLists()
  570. {
  571. string containerTypeName = typeof(Container).AssemblyQualifiedName;
  572. string productListTypeName = typeof(List<Product>).AssemblyQualifiedName;
  573. Container container = new Container
  574. {
  575. In = new List<Product>(),
  576. Out = new List<Product>()
  577. };
  578. string json = JsonConvert.SerializeObject(container, Formatting.Indented,
  579. new JsonSerializerSettings
  580. {
  581. NullValueHandling = NullValueHandling.Ignore,
  582. TypeNameHandling = TypeNameHandling.All,
  583. #pragma warning disable 618
  584. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  585. #pragma warning restore 618
  586. });
  587. StringAssert.AreEqual(@"{
  588. ""$type"": """ + containerTypeName + @""",
  589. ""In"": {
  590. ""$type"": """ + productListTypeName + @""",
  591. ""$values"": []
  592. },
  593. ""Out"": {
  594. ""$type"": """ + productListTypeName + @""",
  595. ""$values"": []
  596. }
  597. }", json);
  598. }
  599. public class TypeNameProperty
  600. {
  601. public string Name { get; set; }
  602. [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
  603. public object Value { get; set; }
  604. }
  605. [Test]
  606. public void WriteObjectTypeNameForProperty()
  607. {
  608. string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof(TypeNameProperty), TypeNameAssemblyFormatHandling.Simple, null);
  609. TypeNameProperty typeNameProperty = new TypeNameProperty
  610. {
  611. Name = "Name!",
  612. Value = new TypeNameProperty
  613. {
  614. Name = "Nested!"
  615. }
  616. };
  617. string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
  618. StringAssert.AreEqual(@"{
  619. ""Name"": ""Name!"",
  620. ""Value"": {
  621. ""$type"": """ + typeNamePropertyRef + @""",
  622. ""Name"": ""Nested!"",
  623. ""Value"": null
  624. }
  625. }", json);
  626. TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
  627. Assert.AreEqual("Name!", deserialized.Name);
  628. CustomAssert.IsInstanceOfType(typeof(TypeNameProperty), deserialized.Value);
  629. TypeNameProperty nested = (TypeNameProperty)deserialized.Value;
  630. Assert.AreEqual("Nested!", nested.Name);
  631. Assert.AreEqual(null, nested.Value);
  632. }
  633. [Test]
  634. public void WriteListTypeNameForProperty()
  635. {
  636. string listRef = ReflectionUtils.GetTypeName(typeof(List<int>), TypeNameAssemblyFormatHandling.Simple, null);
  637. TypeNameProperty typeNameProperty = new TypeNameProperty
  638. {
  639. Name = "Name!",
  640. Value = new List<int> { 1, 2, 3, 4, 5 }
  641. };
  642. string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
  643. StringAssert.AreEqual(@"{
  644. ""Name"": ""Name!"",
  645. ""Value"": {
  646. ""$type"": """ + listRef + @""",
  647. ""$values"": [
  648. 1,
  649. 2,
  650. 3,
  651. 4,
  652. 5
  653. ]
  654. }
  655. }", json);
  656. TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
  657. Assert.AreEqual("Name!", deserialized.Name);
  658. CustomAssert.IsInstanceOfType(typeof(List<int>), deserialized.Value);
  659. List<int> nested = (List<int>)deserialized.Value;
  660. Assert.AreEqual(5, nested.Count);
  661. Assert.AreEqual(1, nested[0]);
  662. Assert.AreEqual(2, nested[1]);
  663. Assert.AreEqual(3, nested[2]);
  664. Assert.AreEqual(4, nested[3]);
  665. Assert.AreEqual(5, nested[4]);
  666. }
  667. [Test]
  668. public void DeserializeUsingCustomBinder()
  669. {
  670. string json = @"{
  671. ""$id"": ""1"",
  672. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
  673. ""Name"": ""Name!""
  674. }";
  675. object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
  676. {
  677. TypeNameHandling = TypeNameHandling.Objects,
  678. #pragma warning disable CS0618 // Type or member is obsolete
  679. Binder = new CustomSerializationBinder()
  680. #pragma warning restore CS0618 // Type or member is obsolete
  681. });
  682. CustomAssert.IsInstanceOfType(typeof(Person), p);
  683. Person person = (Person)p;
  684. Assert.AreEqual("Name!", person.Name);
  685. }
  686. public class CustomSerializationBinder : SerializationBinder
  687. {
  688. public override Type BindToType(string assemblyName, string typeName)
  689. {
  690. return typeof(Person);
  691. }
  692. }
  693. #if !(NET20 || NET35)
  694. [Test]
  695. public void SerializeUsingCustomBinder()
  696. {
  697. TypeNameSerializationBinder binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests");
  698. IList<object> values = new List<object>
  699. {
  700. new Customer
  701. {
  702. Name = "Caroline Customer"
  703. },
  704. new Purchase
  705. {
  706. ProductName = "Elbow Grease",
  707. Price = 5.99m,
  708. Quantity = 1
  709. }
  710. };
  711. string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
  712. {
  713. TypeNameHandling = TypeNameHandling.Auto,
  714. #pragma warning disable CS0618 // Type or member is obsolete
  715. Binder = binder
  716. #pragma warning restore CS0618 // Type or member is obsolete
  717. });
  718. //[
  719. // {
  720. // "$type": "Customer",
  721. // "Name": "Caroline Customer"
  722. // },
  723. // {
  724. // "$type": "Purchase",
  725. // "ProductName": "Elbow Grease",
  726. // "Price": 5.99,
  727. // "Quantity": 1
  728. // }
  729. //]
  730. StringAssert.AreEqual(@"[
  731. {
  732. ""$type"": ""Customer"",
  733. ""Name"": ""Caroline Customer""
  734. },
  735. {
  736. ""$type"": ""Purchase"",
  737. ""ProductName"": ""Elbow Grease"",
  738. ""Price"": 5.99,
  739. ""Quantity"": 1
  740. }
  741. ]", json);
  742. IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
  743. {
  744. TypeNameHandling = TypeNameHandling.Auto,
  745. #pragma warning disable CS0618 // Type or member is obsolete
  746. Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
  747. #pragma warning restore CS0618 // Type or member is obsolete
  748. });
  749. CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]);
  750. Customer customer = (Customer)newValues[0];
  751. Assert.AreEqual("Caroline Customer", customer.Name);
  752. CustomAssert.IsInstanceOfType(typeof(Purchase), newValues[1]);
  753. Purchase purchase = (Purchase)newValues[1];
  754. Assert.AreEqual("Elbow Grease", purchase.ProductName);
  755. }
  756. public class TypeNameSerializationBinder : SerializationBinder
  757. {
  758. public string TypeFormat { get; private set; }
  759. public TypeNameSerializationBinder(string typeFormat)
  760. {
  761. TypeFormat = typeFormat;
  762. }
  763. public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
  764. {
  765. assemblyName = null;
  766. typeName = serializedType.Name;
  767. }
  768. public override Type BindToType(string assemblyName, string typeName)
  769. {
  770. string resolvedTypeName = string.Format(TypeFormat, typeName);
  771. return Type.GetType(resolvedTypeName, true);
  772. }
  773. }
  774. #endif
  775. [Test]
  776. public void NewSerializeUsingCustomBinder()
  777. {
  778. NewTypeNameSerializationBinder binder = new NewTypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests");
  779. IList<object> values = new List<object>
  780. {
  781. new Customer
  782. {
  783. Name = "Caroline Customer"
  784. },
  785. new Purchase
  786. {
  787. ProductName = "Elbow Grease",
  788. Price = 5.99m,
  789. Quantity = 1
  790. }
  791. };
  792. string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
  793. {
  794. TypeNameHandling = TypeNameHandling.Auto,
  795. SerializationBinder = binder
  796. });
  797. //[
  798. // {
  799. // "$type": "Customer",
  800. // "Name": "Caroline Customer"
  801. // },
  802. // {
  803. // "$type": "Purchase",
  804. // "ProductName": "Elbow Grease",
  805. // "Price": 5.99,
  806. // "Quantity": 1
  807. // }
  808. //]
  809. StringAssert.AreEqual(@"[
  810. {
  811. ""$type"": ""Customer"",
  812. ""Name"": ""Caroline Customer""
  813. },
  814. {
  815. ""$type"": ""Purchase"",
  816. ""ProductName"": ""Elbow Grease"",
  817. ""Price"": 5.99,
  818. ""Quantity"": 1
  819. }
  820. ]", json);
  821. IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
  822. {
  823. TypeNameHandling = TypeNameHandling.Auto,
  824. SerializationBinder = new NewTypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
  825. });
  826. CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]);
  827. Customer customer = (Customer)newValues[0];
  828. Assert.AreEqual("Caroline Customer", customer.Name);
  829. CustomAssert.IsInstanceOfType(typeof(Purchase), newValues[1]);
  830. Purchase purchase = (Purchase)newValues[1];
  831. Assert.AreEqual("Elbow Grease", purchase.ProductName);
  832. }
  833. public class NewTypeNameSerializationBinder : ISerializationBinder
  834. {
  835. public string TypeFormat { get; private set; }
  836. public NewTypeNameSerializationBinder(string typeFormat)
  837. {
  838. TypeFormat = typeFormat;
  839. }
  840. public void BindToName(Type serializedType, out string assemblyName, out string typeName)
  841. {
  842. assemblyName = null;
  843. typeName = serializedType.Name;
  844. }
  845. public Type BindToType(string assemblyName, string typeName)
  846. {
  847. string resolvedTypeName = string.Format(TypeFormat, typeName);
  848. return Type.GetType(resolvedTypeName, true);
  849. }
  850. }
  851. [Test]
  852. public void CollectionWithAbstractItems()
  853. {
  854. HolderClass testObject = new HolderClass();
  855. testObject.TestMember = new ContentSubClass("First One");
  856. testObject.AnotherTestMember = new Dictionary<int, IList<ContentBaseClass>>();
  857. testObject.AnotherTestMember.Add(1, new List<ContentBaseClass>());
  858. testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One"));
  859. testObject.AThirdTestMember = new ContentSubClass("Third One");
  860. JsonSerializer serializingTester = new JsonSerializer();
  861. serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
  862. StringWriter sw = new StringWriter();
  863. using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
  864. {
  865. jsonWriter.Formatting = Formatting.Indented;
  866. serializingTester.TypeNameHandling = TypeNameHandling.Auto;
  867. serializingTester.Serialize(jsonWriter, testObject);
  868. }
  869. string json = sw.ToString();
  870. string contentSubClassRef = ReflectionUtils.GetTypeName(typeof(ContentSubClass), TypeNameAssemblyFormatHandling.Simple, null);
  871. string dictionaryRef = ReflectionUtils.GetTypeName(typeof(Dictionary<int, IList<ContentBaseClass>>), TypeNameAssemblyFormatHandling.Simple, null);
  872. string listRef = ReflectionUtils.GetTypeName(typeof(List<ContentBaseClass>), TypeNameAssemblyFormatHandling.Simple, null);
  873. string expected = @"{
  874. ""TestMember"": {
  875. ""$type"": """ + contentSubClassRef + @""",
  876. ""SomeString"": ""First One""
  877. },
  878. ""AnotherTestMember"": {
  879. ""$type"": """ + dictionaryRef + @""",
  880. ""1"": [
  881. {
  882. ""$type"": """ + contentSubClassRef + @""",
  883. ""SomeString"": ""Second One""
  884. }
  885. ]
  886. },
  887. ""AThirdTestMember"": {
  888. ""$type"": """ + contentSubClassRef + @""",
  889. ""SomeString"": ""Third One""
  890. }
  891. }";
  892. StringAssert.AreEqual(expected, json);
  893. StringReader sr = new StringReader(json);
  894. JsonSerializer deserializingTester = new JsonSerializer();
  895. HolderClass anotherTestObject;
  896. using (JsonTextReader jsonReader = new JsonTextReader(sr))
  897. {
  898. deserializingTester.TypeNameHandling = TypeNameHandling.Auto;
  899. anotherTestObject = deserializingTester.Deserialize<HolderClass>(jsonReader);
  900. }
  901. Assert.IsNotNull(anotherTestObject);
  902. CustomAssert.IsInstanceOfType(typeof(ContentSubClass), anotherTestObject.TestMember);
  903. CustomAssert.IsInstanceOfType(typeof(Dictionary<int, IList<ContentBaseClass>>), anotherTestObject.AnotherTestMember);
  904. Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count);
  905. IList<ContentBaseClass> list = anotherTestObject.AnotherTestMember[1];
  906. CustomAssert.IsInstanceOfType(typeof(List<ContentBaseClass>), list);
  907. Assert.AreEqual(1, list.Count);
  908. CustomAssert.IsInstanceOfType(typeof(ContentSubClass), list[0]);
  909. }
  910. [Test]
  911. public void WriteObjectTypeNameForPropertyDemo()
  912. {
  913. Message message = new Message();
  914. message.Address = "http://www.google.com";
  915. message.Body = new SearchDetails
  916. {
  917. Query = "Json.NET",
  918. Language = "en-us"
  919. };
  920. string json = JsonConvert.SerializeObject(message, Formatting.Indented);
  921. // {
  922. // "Address": "http://www.google.com",
  923. // "Body": {
  924. // "$type": "Newtonsoft.Json.Tests.Serialization.SearchDetails, Newtonsoft.Json.Tests",
  925. // "Query": "Json.NET",
  926. // "Language": "en-us"
  927. // }
  928. // }
  929. Message deserialized = JsonConvert.DeserializeObject<Message>(json);
  930. SearchDetails searchDetails = (SearchDetails)deserialized.Body;
  931. // Json.NET
  932. }
  933. public class UrlStatus
  934. {
  935. public int Status { get; set; }
  936. public string Url { get; set; }
  937. }
  938. [Test]
  939. public void GenericDictionaryObject()
  940. {
  941. Dictionary<string, object> collection = new Dictionary<string, object>()
  942. {
  943. { "First", new UrlStatus { Status = 404, Url = @"http://www.bing.com" } },
  944. { "Second", new UrlStatus { Status = 400, Url = @"http://www.google.com" } },
  945. {
  946. "List", new List<UrlStatus>
  947. {
  948. new UrlStatus { Status = 300, Url = @"http://www.yahoo.com" },
  949. new UrlStatus { Status = 200, Url = @"http://www.askjeeves.com" }
  950. }
  951. }
  952. };
  953. string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
  954. {
  955. TypeNameHandling = TypeNameHandling.All,
  956. #pragma warning disable 618
  957. TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
  958. #pragma warning restore 618
  959. });
  960. string urlStatusTypeName = ReflectionUtils.GetTypeName(typeof(UrlStatus), TypeNameAssemblyFormatHandling.Simple, null);
  961. StringAssert.AreEqual(@"{
  962. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
  963. ""First"": {
  964. ""$type"": """ + urlStatusTypeName + @""",
  965. ""Status"": 404,
  966. ""Url"": ""http://www.bing.com""
  967. },
  968. ""Second"": {
  969. ""$type"": """ + urlStatusTypeName + @""",
  970. ""Status"": 400,
  971. ""Url"": ""http://www.google.com""
  972. },
  973. ""List"": {
  974. ""$type"": ""System.Collections.Generic.List`1[[" + urlStatusTypeName + @"]], mscorlib"",
  975. ""$values"": [
  976. {
  977. ""$type"": """ + urlStatusTypeName + @""",
  978. ""Status"": 300,
  979. ""Url"": ""http://www.yahoo.com""
  980. },
  981. {
  982. ""$type"": """ + urlStatusTypeName + @""",
  983. ""Status"": 200,
  984. ""Url"": ""http://www.askjeeves.com""
  985. }
  986. ]
  987. }
  988. }", json);
  989. object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
  990. {
  991. TypeNameHandling = TypeNameHandling.All,
  992. #pragma warning disable 618
  993. TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
  994. #pragma warning restore 618
  995. });
  996. CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c);
  997. Dictionary<string, object> newCollection = (Dictionary<string, object>)c;
  998. Assert.AreEqual(3, newCollection.Count);
  999. Assert.AreEqual(@"http://www.bing.com", ((UrlStatus)newCollection["First"]).Url);
  1000. List<UrlStatus> statues = (List<UrlStatus>)newCollection["List"];
  1001. Assert.AreEqual(2, statues.Count);
  1002. }
  1003. [Test]
  1004. public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo()
  1005. {
  1006. string productClassRef = ReflectionUtils.GetTypeName(typeof(CustomEnumerable<Product>), TypeNameAssemblyFormatHandling.Simple, null);
  1007. CustomEnumerable<Product> products = new CustomEnumerable<Product>();
  1008. string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
  1009. StringAssert.AreEqual(@"{
  1010. ""$type"": """ + productClassRef + @""",
  1011. ""$values"": []
  1012. }", json);
  1013. }
  1014. public class CustomEnumerable<T> : IEnumerable<T>
  1015. {
  1016. //NOTE: a simple linked list
  1017. private readonly T value;
  1018. private readonly CustomEnumerable<T> next;
  1019. private readonly int count;
  1020. private CustomEnumerable(T value, CustomEnumerable<T> next)
  1021. {
  1022. this.value = value;
  1023. this.next = next;
  1024. count = this.next.count + 1;
  1025. }
  1026. public CustomEnumerable()
  1027. {
  1028. count = 0;
  1029. }
  1030. public CustomEnumerable<T> AddFirst(T newVal)
  1031. {
  1032. return new CustomEnumerable<T>(newVal, this);
  1033. }
  1034. public IEnumerator<T> GetEnumerator()
  1035. {
  1036. if (count == 0) // last node
  1037. {
  1038. yield break;
  1039. }
  1040. yield return value;
  1041. var nextInLine = next;
  1042. while (nextInLine != null)
  1043. {
  1044. if (nextInLine.count != 0)
  1045. {
  1046. yield return nextInLine.value;
  1047. }
  1048. nextInLine = nextInLine.next;
  1049. }
  1050. }
  1051. IEnumerator IEnumerable.GetEnumerator()
  1052. {
  1053. return GetEnumerator();
  1054. }
  1055. }
  1056. public class Car
  1057. {
  1058. // included in JSON
  1059. public string Model { get; set; }
  1060. public DateTime Year { get; set; }
  1061. public List<string> Features { get; set; }
  1062. public object[] Objects { get; set; }
  1063. // ignored
  1064. [JsonIgnore]
  1065. public DateTime LastModified { get; set; }
  1066. }
  1067. [Test]
  1068. public void ByteArrays()
  1069. {
  1070. Car testerObject = new Car();
  1071. testerObject.Year = new DateTime(2000, 10, 5, 1, 1, 1, DateTimeKind.Utc);
  1072. byte[] data = new byte[] { 75, 65, 82, 73, 82, 65 };
  1073. testerObject.Objects = new object[] { data, "prueba" };
  1074. JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
  1075. jsonSettings.NullValueHandling = NullValueHandling.Ignore;
  1076. jsonSettings.TypeNameHandling = TypeNameHandling.All;
  1077. string output = JsonConvert.SerializeObject(testerObject, Formatting.Indented, jsonSettings);
  1078. string carClassRef = ReflectionUtils.GetTypeName(typeof(Car), TypeNameAssemblyFormatHandling.Simple, null);
  1079. StringAssert.AreEqual(output, @"{
  1080. ""$type"": """ + carClassRef + @""",
  1081. ""Year"": ""2000-10-05T01:01:01Z"",
  1082. ""Objects"": {
  1083. ""$type"": ""System.Object[], mscorlib"",
  1084. ""$values"": [
  1085. {
  1086. ""$type"": ""System.Byte[], mscorlib"",
  1087. ""$value"": ""S0FSSVJB""
  1088. },
  1089. ""prueba""
  1090. ]
  1091. }
  1092. }");
  1093. Car obj = JsonConvert.DeserializeObject<Car>(output, jsonSettings);
  1094. Assert.IsNotNull(obj);
  1095. Assert.IsTrue(obj.Objects[0] is byte[]);
  1096. byte[] d = (byte[])obj.Objects[0];
  1097. CollectionAssert.AreEquivalent(data, d);
  1098. }
  1099. #if !(DNXCORE50)
  1100. [Test]
  1101. public void ISerializableTypeNameHandlingTest()
  1102. {
  1103. //Create an instance of our example type
  1104. IExample e = new Example("Rob");
  1105. SerializableWrapper w = new SerializableWrapper
  1106. {
  1107. Content = e
  1108. };
  1109. //Test Binary Serialization Round Trip
  1110. //This will work find because the Binary Formatter serializes type names
  1111. //this.TestBinarySerializationRoundTrip(e);
  1112. //Test Json Serialization
  1113. //This fails because the JsonSerializer doesn't serialize type names correctly for ISerializable objects
  1114. //Type Names should be serialized for All, Auto and Object modes
  1115. TestJsonSerializationRoundTrip(w, TypeNameHandling.All);
  1116. TestJsonSerializationRoundTrip(w, TypeNameHandling.Auto);
  1117. TestJsonSerializationRoundTrip(w, TypeNameHandling.Objects);
  1118. }
  1119. private void TestJsonSerializationRoundTrip(SerializableWrapper e, TypeNameHandling flag)
  1120. {
  1121. StringWriter writer = new StringWriter();
  1122. //Create our serializer and set Type Name Handling appropriately
  1123. JsonSerializer serializer = new JsonSerializer();
  1124. serializer.TypeNameHandling = flag;
  1125. //Do the actual serialization and dump to Console for inspection
  1126. serializer.Serialize(new JsonTextWriter(writer), e);
  1127. //Now try to deserialize
  1128. //Json.Net will cause an error here as it will try and instantiate
  1129. //the interface directly because it failed to respect the
  1130. //TypeNameHandling property on serialization
  1131. SerializableWrapper f = serializer.Deserialize<SerializableWrapper>(new JsonTextReader(new StringReader(writer.ToString())));
  1132. //Check Round Trip
  1133. Assert.AreEqual(e, f, "Objects should be equal after round trip json serialization");
  1134. }
  1135. #endif
  1136. #if !(NET20 || NET35)
  1137. [Test]
  1138. public void SerializationBinderWithFullName()
  1139. {
  1140. Message message = new Message
  1141. {
  1142. Address = "jamesnk@testtown.com",
  1143. Body = new Version(1, 2, 3, 4)
  1144. };
  1145. string json = JsonConvert.SerializeObject(message, Formatting.Indented, new JsonSerializerSettings
  1146. {
  1147. TypeNameHandling = TypeNameHandling.All,
  1148. #pragma warning disable CS0618 // Type or member is obsolete
  1149. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
  1150. Binder = new MetroBinder(),
  1151. #pragma warning restore CS0618 // Type or member is obsolete
  1152. ContractResolver = new DefaultContractResolver
  1153. {
  1154. #if !(PORTABLE || DNXCORE50)
  1155. IgnoreSerializableAttribute = true
  1156. #endif
  1157. }
  1158. });
  1159. StringAssert.AreEqual(@"{
  1160. ""$type"": "":::MESSAGE:::, AssemblyName"",
  1161. ""Address"": ""jamesnk@testtown.com"",
  1162. ""Body"": {
  1163. ""$type"": "":::VERSION:::, AssemblyName"",
  1164. ""Major"": 1,
  1165. ""Minor"": 2,
  1166. ""Build"": 3,
  1167. ""Revision"": 4,
  1168. ""MajorRevision"": 0,
  1169. ""MinorRevision"": 4
  1170. }
  1171. }", json);
  1172. }
  1173. public class MetroBinder : SerializationBinder
  1174. {
  1175. public override Type BindToType(string assemblyName, string typeName)
  1176. {
  1177. return null;
  1178. }
  1179. public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
  1180. {
  1181. assemblyName = "AssemblyName";
  1182. #if !(DNXCORE50)
  1183. typeName = ":::" + serializedType.Name.ToUpper(CultureInfo.InvariantCulture) + ":::";
  1184. #else
  1185. typeName = ":::" + serializedType.Name.ToUpper() + ":::";
  1186. #endif
  1187. }
  1188. }
  1189. #endif
  1190. [Test]
  1191. public void TypeNameIntList()
  1192. {
  1193. TypeNameList<int> l = new TypeNameList<int>();
  1194. l.Add(1);
  1195. l.Add(2);
  1196. l.Add(3);
  1197. string json = JsonConvert.SerializeObject(l, Formatting.Indented);
  1198. StringAssert.AreEqual(@"[
  1199. 1,
  1200. 2,
  1201. 3
  1202. ]", json);
  1203. }
  1204. [Test]
  1205. public void TypeNameComponentList()
  1206. {
  1207. var c1 = new TestComponentSimple();
  1208. TypeNameList<object> l = new TypeNameList<object>();
  1209. l.Add(c1);
  1210. l.Add(new Employee
  1211. {
  1212. BirthDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc),
  1213. Department = "Department!"
  1214. });
  1215. l.Add("String!");
  1216. l.Add(long.MaxValue);
  1217. string json = JsonConvert.SerializeObject(l, Formatting.Indented);
  1218. StringAssert.AreEqual(@"[
  1219. {
  1220. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1221. ""MyProperty"": 0
  1222. },
  1223. {
  1224. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.Employee, Newtonsoft.Json.Tests"",
  1225. ""FirstName"": null,
  1226. ""LastName"": null,
  1227. ""BirthDate"": ""2000-12-12T12:12:12Z"",
  1228. ""Department"": ""Department!"",
  1229. ""JobTitle"": null
  1230. },
  1231. ""String!"",
  1232. 9223372036854775807
  1233. ]", json);
  1234. TypeNameList<object> l2 = JsonConvert.DeserializeObject<TypeNameList<object>>(json);
  1235. Assert.AreEqual(4, l2.Count);
  1236. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), l2[0]);
  1237. CustomAssert.IsInstanceOfType(typeof(Employee), l2[1]);
  1238. CustomAssert.IsInstanceOfType(typeof(string), l2[2]);
  1239. CustomAssert.IsInstanceOfType(typeof(long), l2[3]);
  1240. }
  1241. [Test]
  1242. public void TypeNameDictionary()
  1243. {
  1244. TypeNameDictionary<object> l = new TypeNameDictionary<object>();
  1245. l.Add("First", new TestComponentSimple { MyProperty = 1 });
  1246. l.Add("Second", "String!");
  1247. l.Add("Third", long.MaxValue);
  1248. string json = JsonConvert.SerializeObject(l, Formatting.Indented);
  1249. StringAssert.AreEqual(@"{
  1250. ""First"": {
  1251. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1252. ""MyProperty"": 1
  1253. },
  1254. ""Second"": ""String!"",
  1255. ""Third"": 9223372036854775807
  1256. }", json);
  1257. TypeNameDictionary<object> l2 = JsonConvert.DeserializeObject<TypeNameDictionary<object>>(json);
  1258. Assert.AreEqual(3, l2.Count);
  1259. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), l2["First"]);
  1260. Assert.AreEqual(1, ((TestComponentSimple)l2["First"]).MyProperty);
  1261. CustomAssert.IsInstanceOfType(typeof(string), l2["Second"]);
  1262. CustomAssert.IsInstanceOfType(typeof(long), l2["Third"]);
  1263. }
  1264. [Test]
  1265. public void TypeNameObjectItems()
  1266. {
  1267. TypeNameObject o1 = new TypeNameObject();
  1268. o1.Object1 = new TestComponentSimple { MyProperty = 1 };
  1269. o1.Object2 = 123;
  1270. o1.ObjectNotHandled = new TestComponentSimple { MyProperty = int.MaxValue };
  1271. o1.String = "String!";
  1272. o1.Integer = int.MaxValue;
  1273. string json = JsonConvert.SerializeObject(o1, Formatting.Indented);
  1274. string expected = @"{
  1275. ""Object1"": {
  1276. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1277. ""MyProperty"": 1
  1278. },
  1279. ""Object2"": 123,
  1280. ""ObjectNotHandled"": {
  1281. ""MyProperty"": 2147483647
  1282. },
  1283. ""String"": ""String!"",
  1284. ""Integer"": 2147483647
  1285. }";
  1286. StringAssert.AreEqual(expected, json);
  1287. TypeNameObject o2 = JsonConvert.DeserializeObject<TypeNameObject>(json);
  1288. Assert.IsNotNull(o2);
  1289. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), o2.Object1);
  1290. Assert.AreEqual(1, ((TestComponentSimple)o2.Object1).MyProperty);
  1291. CustomAssert.IsInstanceOfType(typeof(long), o2.Object2);
  1292. CustomAssert.IsInstanceOfType(typeof(JObject), o2.ObjectNotHandled);
  1293. StringAssert.AreEqual(@"{
  1294. ""MyProperty"": 2147483647
  1295. }", o2.ObjectNotHandled.ToString());
  1296. }
  1297. [Test]
  1298. public void PropertyItemTypeNameHandling()
  1299. {
  1300. PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling();
  1301. c1.Data = new List<object>
  1302. {
  1303. 1,
  1304. "two",
  1305. new TestComponentSimple { MyProperty = 1 }
  1306. };
  1307. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  1308. StringAssert.AreEqual(@"{
  1309. ""Data"": [
  1310. 1,
  1311. ""two"",
  1312. {
  1313. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1314. ""MyProperty"": 1
  1315. }
  1316. ]
  1317. }", json);
  1318. PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
  1319. Assert.AreEqual(3, c2.Data.Count);
  1320. CustomAssert.IsInstanceOfType(typeof(long), c2.Data[0]);
  1321. CustomAssert.IsInstanceOfType(typeof(string), c2.Data[1]);
  1322. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data[2]);
  1323. TestComponentSimple c = (TestComponentSimple)c2.Data[2];
  1324. Assert.AreEqual(1, c.MyProperty);
  1325. }
  1326. [Test]
  1327. public void PropertyItemTypeNameHandlingNestedCollections()
  1328. {
  1329. PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling
  1330. {
  1331. Data = new List<object>
  1332. {
  1333. new TestComponentSimple { MyProperty = 1 },
  1334. new List<object>
  1335. {
  1336. new List<object>
  1337. {
  1338. new List<object>()
  1339. }
  1340. }
  1341. }
  1342. };
  1343. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  1344. StringAssert.AreEqual(@"{
  1345. ""Data"": [
  1346. {
  1347. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1348. ""MyProperty"": 1
  1349. },
  1350. {
  1351. ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
  1352. ""$values"": [
  1353. [
  1354. []
  1355. ]
  1356. ]
  1357. }
  1358. ]
  1359. }", json);
  1360. PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
  1361. Assert.AreEqual(2, c2.Data.Count);
  1362. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data[0]);
  1363. CustomAssert.IsInstanceOfType(typeof(List<object>), c2.Data[1]);
  1364. List<object> c = (List<object>)c2.Data[1];
  1365. CustomAssert.IsInstanceOfType(typeof(JArray), c[0]);
  1366. json = @"{
  1367. ""Data"": [
  1368. {
  1369. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1370. ""MyProperty"": 1
  1371. },
  1372. {
  1373. ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
  1374. ""$values"": [
  1375. {
  1376. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1377. ""MyProperty"": 1
  1378. }
  1379. ]
  1380. }
  1381. ]
  1382. }";
  1383. c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandling>(json);
  1384. Assert.AreEqual(2, c2.Data.Count);
  1385. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data[0]);
  1386. CustomAssert.IsInstanceOfType(typeof(List<object>), c2.Data[1]);
  1387. c = (List<object>)c2.Data[1];
  1388. CustomAssert.IsInstanceOfType(typeof(JObject), c[0]);
  1389. JObject o = (JObject)c[0];
  1390. Assert.AreEqual(1, (int)o["MyProperty"]);
  1391. }
  1392. [Test]
  1393. public void PropertyItemTypeNameHandlingNestedDictionaries()
  1394. {
  1395. PropertyItemTypeNameHandlingDictionary c1 = new PropertyItemTypeNameHandlingDictionary()
  1396. {
  1397. Data = new Dictionary<string, object>
  1398. {
  1399. {
  1400. "one", new TestComponentSimple { MyProperty = 1 }
  1401. },
  1402. {
  1403. "two", new Dictionary<string, object>
  1404. {
  1405. {
  1406. "one", new Dictionary<string, object>
  1407. {
  1408. { "one", 1 }
  1409. }
  1410. }
  1411. }
  1412. }
  1413. }
  1414. };
  1415. string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
  1416. StringAssert.AreEqual(@"{
  1417. ""Data"": {
  1418. ""one"": {
  1419. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1420. ""MyProperty"": 1
  1421. },
  1422. ""two"": {
  1423. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
  1424. ""one"": {
  1425. ""one"": 1
  1426. }
  1427. }
  1428. }
  1429. }", json);
  1430. PropertyItemTypeNameHandlingDictionary c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDictionary>(json);
  1431. Assert.AreEqual(2, c2.Data.Count);
  1432. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data["one"]);
  1433. CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c2.Data["two"]);
  1434. Dictionary<string, object> c = (Dictionary<string, object>)c2.Data["two"];
  1435. CustomAssert.IsInstanceOfType(typeof(JObject), c["one"]);
  1436. json = @"{
  1437. ""Data"": {
  1438. ""one"": {
  1439. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1440. ""MyProperty"": 1
  1441. },
  1442. ""two"": {
  1443. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
  1444. ""one"": {
  1445. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1446. ""MyProperty"": 1
  1447. }
  1448. }
  1449. }
  1450. }";
  1451. c2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDictionary>(json);
  1452. Assert.AreEqual(2, c2.Data.Count);
  1453. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data["one"]);
  1454. CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c2.Data["two"]);
  1455. c = (Dictionary<string, object>)c2.Data["two"];
  1456. CustomAssert.IsInstanceOfType(typeof(JObject), c["one"]);
  1457. JObject o = (JObject)c["one"];
  1458. Assert.AreEqual(1, (int)o["MyProperty"]);
  1459. }
  1460. [Test]
  1461. public void PropertyItemTypeNameHandlingObject()
  1462. {
  1463. PropertyItemTypeNameHandlingObject o1 = new PropertyItemTypeNameHandlingObject
  1464. {
  1465. Data = new TypeNameHandlingTestObject
  1466. {
  1467. Prop1 = new List<object>
  1468. {
  1469. new TestComponentSimple
  1470. {
  1471. MyProperty = 1
  1472. }
  1473. },
  1474. Prop2 = new TestComponentSimple
  1475. {
  1476. MyProperty = 1
  1477. },
  1478. Prop3 = 3,
  1479. Prop4 = new JObject()
  1480. }
  1481. };
  1482. string json = JsonConvert.SerializeObject(o1, Formatting.Indented);
  1483. StringAssert.AreEqual(@"{
  1484. ""Data"": {
  1485. ""Prop1"": {
  1486. ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"",
  1487. ""$values"": [
  1488. {
  1489. ""MyProperty"": 1
  1490. }
  1491. ]
  1492. },
  1493. ""Prop2"": {
  1494. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1495. ""MyProperty"": 1
  1496. },
  1497. ""Prop3"": 3,
  1498. ""Prop4"": {}
  1499. }
  1500. }", json);
  1501. PropertyItemTypeNameHandlingObject o2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingObject>(json);
  1502. Assert.IsNotNull(o2);
  1503. Assert.IsNotNull(o2.Data);
  1504. CustomAssert.IsInstanceOfType(typeof(List<object>), o2.Data.Prop1);
  1505. CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), o2.Data.Prop2);
  1506. CustomAssert.IsInstanceOfType(typeof(long), o2.Data.Prop3);
  1507. CustomAssert.IsInstanceOfType(typeof(JObject), o2.Data.Prop4);
  1508. List<object> o = (List<object>)o2.Data.Prop1;
  1509. JObject j = (JObject)o[0];
  1510. Assert.AreEqual(1, (int)j["MyProperty"]);
  1511. }
  1512. #if !(NET35 || NET20 || PORTABLE40)
  1513. [Test]
  1514. public void PropertyItemTypeNameHandlingDynamic()
  1515. {
  1516. PropertyItemTypeNameHandlingDynamic d1 = new PropertyItemTypeNameHandlingDynamic();
  1517. dynamic data = new DynamicDictionary();
  1518. data.one = new TestComponentSimple
  1519. {
  1520. MyProperty = 1
  1521. };
  1522. dynamic data2 = new DynamicDictionary();
  1523. data2.one = new TestComponentSimple
  1524. {
  1525. MyProperty = 2
  1526. };
  1527. data.two = data2;
  1528. d1.Data = (DynamicDictionary)data;
  1529. string json = JsonConvert.SerializeObject(d1, Formatting.Indented);
  1530. StringAssert.AreEqual(@"{
  1531. ""Data"": {
  1532. ""one"": {
  1533. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1534. ""MyProperty"": 1
  1535. },
  1536. ""two"": {
  1537. ""$type"": ""Newtonsoft.Json.Tests.Linq.DynamicDictionary, Newtonsoft.Json.Tests"",
  1538. ""one"": {
  1539. ""MyProperty"": 2
  1540. }
  1541. }
  1542. }
  1543. }", json);
  1544. PropertyItemTypeNameHandlingDynamic d2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDynamic>(json);
  1545. Assert.IsNotNull(d2);
  1546. Assert.IsNotNull(d2.Data);
  1547. dynamic data3 = d2.Data;
  1548. TestComponentSimple c = (TestComponentSimple)data3.one;
  1549. Assert.AreEqual(1, c.MyProperty);
  1550. dynamic data4 = data3.two;
  1551. JObject o = (JObject)data4.one;
  1552. Assert.AreEqual(2, (int)o["MyProperty"]);
  1553. json = @"{
  1554. ""Data"": {
  1555. ""one"": {
  1556. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1557. ""MyProperty"": 1
  1558. },
  1559. ""two"": {
  1560. ""$type"": ""Newtonsoft.Json.Tests.Linq.DynamicDictionary, Newtonsoft.Json.Tests"",
  1561. ""one"": {
  1562. ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
  1563. ""MyProperty"": 2
  1564. }
  1565. }
  1566. }
  1567. }";
  1568. d2 = JsonConvert.DeserializeObject<PropertyItemTypeNameHandlingDynamic>(json);
  1569. data3 = d2.Data;
  1570. data4 = data3.two;
  1571. o = (JObject)data4.one;
  1572. Assert.AreEqual(2, (int)o["MyProperty"]);
  1573. }
  1574. #endif
  1575. #if !(DNXCORE50)
  1576. [Test]
  1577. public void SerializeDeserialize_DictionaryContextContainsGuid_DeserializesItemAsGuid()
  1578. {
  1579. const string contextKey = "k1";
  1580. var someValue = new Guid("a6e986df-fc2c-4906-a1ef-9492388f7833");
  1581. Dictionary<string, Guid> inputContext = new Dictionary<string, Guid>();
  1582. inputContext.Add(contextKey, someValue);
  1583. JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings()
  1584. {
  1585. Formatting = Formatting.Indented,
  1586. TypeNameHandling = TypeNameHandling.All
  1587. };
  1588. string serializedString = JsonConvert.SerializeObject(inputContext, jsonSerializerSettings);
  1589. StringAssert.AreEqual(@"{
  1590. ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Guid, mscorlib]], mscorlib"",
  1591. ""k1"": ""a6e986df-fc2c-4906-a1ef-9492388f7833""
  1592. }", serializedString);
  1593. var deserializedObject = (Dictionary<string, Guid>)JsonConvert.DeserializeObject(serializedString, jsonSerializerSettings);
  1594. Assert.AreEqual(someValue, deserializedObject[contextKey]);
  1595. }
  1596. [Test]
  1597. public void TypeNameHandlingWithISerializableValues()
  1598. {
  1599. MyParent p = new MyParent
  1600. {
  1601. Child = new MyChild
  1602. {
  1603. MyProperty = "string!"
  1604. }
  1605. };
  1606. JsonSerializerSettings settings = new JsonSerializerSettings
  1607. {
  1608. TypeNameHandling = TypeNameHandling.Auto,
  1609. DateFormatHandling = DateFormatHandling.IsoDateFormat,
  1610. MissingMemberHandling = MissingMemberHandling.Ignore,
  1611. DefaultValueHandling = DefaultValueHandling.Ignore,
  1612. NullValueHandling = NullValueHandling.Ignore,
  1613. Formatting = Formatting.Indented
  1614. };
  1615. string json = JsonConvert.SerializeObject(p, settings);
  1616. StringAssert.AreEqual(@"{
  1617. ""c"": {
  1618. ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChild, Newtonsoft.Json.Tests"",
  1619. ""p"": ""string!""
  1620. }
  1621. }", json);
  1622. MyParent p2 = JsonConvert.DeserializeObject<MyParent>(json, settings);
  1623. CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child);
  1624. Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty);
  1625. }
  1626. [Test]
  1627. public void TypeNameHandlingWithISerializableValuesAndArray()
  1628. {
  1629. MyParent p = new MyParent
  1630. {
  1631. Child = new MyChildList
  1632. {
  1633. "string!"
  1634. }
  1635. };
  1636. JsonSerializerSettings settings = new JsonSerializerSettings
  1637. {
  1638. TypeNameHandling = TypeNameHandling.Auto,
  1639. DateFormatHandling = DateFormatHandling.IsoDateFormat,
  1640. MissingMemberHandling = MissingMemberHandling.Ignore,
  1641. DefaultValueHandling = DefaultValueHandling.Ignore,
  1642. NullValueHandling = NullValueHandling.Ignore,
  1643. Formatting = Formatting.Indented
  1644. };
  1645. string json = JsonConvert.SerializeObject(p, settings);
  1646. StringAssert.AreEqual(@"{
  1647. ""c"": {
  1648. ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChildList, Newtonsoft.Json.Tests"",
  1649. ""$values"": [
  1650. ""string!""
  1651. ]
  1652. }
  1653. }", json);
  1654. MyParent p2 = JsonConvert.DeserializeObject<MyParent>(json, settings);
  1655. CustomAssert.IsInstanceOfType(typeof(MyChildList), p2.Child);
  1656. Assert.AreEqual(1, ((MyChildList)p2.Child).Count);
  1657. Assert.AreEqual("string!", ((MyChildList)p2.Child)[0]);
  1658. }
  1659. [Test]
  1660. public void ParentTypeNameHandlingWithISerializableValues()
  1661. {
  1662. ParentParent pp = new ParentParent();
  1663. pp.ParentProp = new MyParent
  1664. {
  1665. Child = new MyChild
  1666. {
  1667. MyProperty = "string!"
  1668. }
  1669. };
  1670. JsonSerializerSettings settings = new JsonSerializerSettings
  1671. {
  1672. DateFormatHandling = DateFormatHandling.IsoDateFormat,
  1673. MissingMemberHandling = MissingMemberHandling.Ignore,
  1674. DefaultValueHandling = DefaultValueHandling.Ignore,
  1675. NullValueHandling = NullValueHandling.Ignore,
  1676. Formatting = Formatting.Indented
  1677. };
  1678. string json = JsonConvert.SerializeObject(pp, settings);
  1679. StringAssert.AreEqual(@"{
  1680. ""ParentProp"": {
  1681. ""c"": {
  1682. ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChild, Newtonsoft.Json.Tests"",
  1683. ""p"": ""string!""
  1684. }
  1685. }
  1686. }", json);
  1687. ParentParent pp2 = JsonConvert.DeserializeObject<ParentParent>(json, settings);
  1688. MyParent p2 = pp2.ParentProp;
  1689. CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child);
  1690. Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty);
  1691. }
  1692. #endif
  1693. [Test]
  1694. public void ListOfStackWithFullAssemblyName()
  1695. {
  1696. var input = new List<Stack<string>>();
  1697. input.Add(new Stack<string>(new List<string> { "One", "Two", "Three" }));
  1698. input.Add(new Stack<string>(new List<string> { "Four", "Five", "Six" }));
  1699. input.Add(new Stack<string>(new List<string> { "Seven", "Eight", "Nine" }));
  1700. string serialized = JsonConvert.SerializeObject(input,
  1701. Newtonsoft.Json.Formatting.Indented,
  1702. new JsonSerializerSettings
  1703. {
  1704. TypeNameHandling = TypeNameHandling.All,
  1705. #pragma warning disable 618
  1706. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full // TypeNameHandling.Auto will work
  1707. #pragma warning restore 618
  1708. });
  1709. var output = JsonConvert.DeserializeObject<List<Stack<string>>>(serialized,
  1710. new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }
  1711. );
  1712. List<string> strings = output.SelectMany(s => s).ToList();
  1713. Assert.AreEqual(9, strings.Count);
  1714. Assert.AreEqual("One", strings[0]);
  1715. Assert.AreEqual("Nine", strings[8]);
  1716. }
  1717. #if !NET20
  1718. [Test]
  1719. public void ExistingBaseValue()
  1720. {
  1721. string json = @"{
  1722. ""itemIdentifier"": {
  1723. ""$type"": ""Newtonsoft.Json.Tests.Serialization.ReportItemKeys, Newtonsoft.Json.Tests"",
  1724. ""dataType"": 0,
  1725. ""wantedUnitID"": 1,
  1726. ""application"": 3,
  1727. ""id"": 101,
  1728. ""name"": ""Machine""
  1729. },
  1730. ""isBusinessEntity"": false,
  1731. ""isKeyItem"": true,
  1732. ""summarizeOnThisItem"": false
  1733. }";
  1734. GroupingInfo g = JsonConvert.DeserializeObject<GroupingInfo>(json, new JsonSerializerSettings
  1735. {
  1736. TypeNameHandling = TypeNameHandling.Objects
  1737. });
  1738. ReportItemKeys item = (ReportItemKeys)g.ItemIdentifier;
  1739. Assert.AreEqual(1UL, item.WantedUnitID);
  1740. }
  1741. #endif
  1742. #if !(NET20 || NET35)
  1743. [Test]
  1744. public void GenericItemTypeCollection()
  1745. {
  1746. DataType data = new DataType();
  1747. data.Rows.Add("key", new List<MyInterfaceImplementationType> { new MyInterfaceImplementationType() { SomeProperty = "property" } });
  1748. string serialized = JsonConvert.SerializeObject(data, Formatting.Indented);
  1749. StringAssert.AreEqual(@"{
  1750. ""Rows"": {
  1751. ""key"": {
  1752. ""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.MyInterfaceImplementationType, Newtonsoft.Json.Tests]], mscorlib"",
  1753. ""$values"": [
  1754. {
  1755. ""SomeProperty"": ""property""
  1756. }
  1757. ]
  1758. }
  1759. }
  1760. }", serialized);
  1761. DataType deserialized = JsonConvert.DeserializeObject<DataType>(serialized);
  1762. Assert.AreEqual("property", deserialized.Rows["key"].First().SomeProperty);
  1763. }
  1764. #endif
  1765. #if !(NET20 || PORTABLE || PORTABLE40)
  1766. [Test]
  1767. public void DeserializeComplexGenericDictionary_Simple()
  1768. {
  1769. JsonSerializerSettings serializerSettings = new JsonSerializerSettings
  1770. {
  1771. TypeNameHandling = TypeNameHandling.All,
  1772. #pragma warning disable 618
  1773. TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
  1774. #pragma warning restore 618
  1775. };
  1776. Dictionary<int, HashSet<string>> dictionary = new Dictionary<int, HashSet<string>>
  1777. {
  1778. { 1, new HashSet<string>(new[] { "test" }) },
  1779. };
  1780. string obtainedJson = JsonConvert.SerializeObject(dictionary, serializerSettings);
  1781. Dictionary<int, HashSet<string>> obtainedDictionary = (Dictionary<int, HashSet<string>>)JsonConvert.DeserializeObject(obtainedJson, serializerSettings);
  1782. Assert.IsNotNull(obtainedDictionary);
  1783. }
  1784. [Test]
  1785. public void DeserializeComplexGenericDictionary_Full()
  1786. {
  1787. JsonSerializerSettings serializerSettings = new JsonSerializerSettings
  1788. {
  1789. TypeNameHandling = TypeNameHandling.All,
  1790. #pragma warning disable 618
  1791. TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
  1792. #pragma warning restore 618
  1793. };
  1794. Dictionary<int, HashSet<string>> dictionary = new Dictionary<int, HashSet<string>>
  1795. {
  1796. { 1, new HashSet<string>(new[] { "test" }) },
  1797. };
  1798. string obtainedJson = JsonConvert.SerializeObject(dictionary, serializerSettings);
  1799. Dictionary<int, HashSet<string>> obtainedDictionary = (Dictionary<int, HashSet<string>>)JsonConvert.DeserializeObject(obtainedJson, serializerSettings);
  1800. Assert.IsNotNull(obtainedDictionary);
  1801. }
  1802. [Test]
  1803. public void SerializeNullableStructProperty_Auto()
  1804. {
  1805. JsonSerializerSettings serializerSettings = new JsonSerializerSettings
  1806. {
  1807. TypeNameHandling = TypeNameHandling.Auto,
  1808. Formatting = Formatting.Indented
  1809. };
  1810. ObjectWithOptionalMessage objWithMessage = new ObjectWithOptionalMessage(new Message2("Hello!"));
  1811. string json = JsonConvert.SerializeObject(objWithMessage, serializerSettings);
  1812. StringAssert.AreEqual(@"{
  1813. ""Message"": {
  1814. ""Value"": ""Hello!""
  1815. }
  1816. }", json);
  1817. }
  1818. [Test]
  1819. public void DeserializeNullableStructProperty_Auto()
  1820. {
  1821. JsonSerializerSettings serializerSettings = new JsonSerializerSettings
  1822. {
  1823. TypeNameHandling = TypeNameHandling.Auto,
  1824. Formatting = Formatting.Indented
  1825. };
  1826. string json = @"{
  1827. ""Message"": {
  1828. ""Value"": ""Hello!""
  1829. }
  1830. }";
  1831. ObjectWithOptionalMessage objWithMessage = JsonConvert.DeserializeObject<ObjectWithOptionalMessage>(json, serializerSettings);
  1832. StringAssert.AreEqual("Hello!", objWithMessage.Message.Value.Value);
  1833. }
  1834. #endif
  1835. #if !(NET20 || NET35)
  1836. [Test]
  1837. public void SerializerWithDefaultBinder()
  1838. {
  1839. var serializer = JsonSerializer.Create();
  1840. #pragma warning disable CS0618
  1841. Assert.NotNull(serializer.Binder);
  1842. Assert.IsInstanceOf(typeof(DefaultSerializationBinder), serializer.Binder);
  1843. #pragma warning restore CS0618 // Type or member is obsolete
  1844. Assert.IsInstanceOf(typeof(DefaultSerializationBinder), serializer.SerializationBinder);
  1845. }
  1846. [Test]
  1847. public void ObsoleteBinderThrowsIfISerializationBinderSet()
  1848. {
  1849. var serializer = JsonSerializer.Create(new JsonSerializerSettings() { SerializationBinder = new FancyBinder() });
  1850. ExceptionAssert.Throws<InvalidOperationException>(() =>
  1851. {
  1852. #pragma warning disable CS0618 // Type or member is obsolete
  1853. var serializationBinder = serializer.Binder;
  1854. #pragma warning restore CS0618 // Type or member is obsolete
  1855. serializationBinder.ToString();
  1856. }, "Cannot get SerializationBinder because an ISerializationBinder was previously set.");
  1857. Assert.IsInstanceOf(typeof(FancyBinder), serializer.SerializationBinder);
  1858. }
  1859. [Test]
  1860. public void SetOldBinderAndSerializationBinderReturnsWrapper()
  1861. {
  1862. #pragma warning disable CS0618 // Type or member is obsolete
  1863. var serializer = JsonSerializer.Create(new JsonSerializerSettings() { Binder = new OldBinder() });
  1864. Assert.IsInstanceOf(typeof(OldBinder), serializer.Binder);
  1865. #pragma warning restore CS0618 // Type or member is obsolete
  1866. var binder = serializer.SerializationBinder;
  1867. Assert.IsInstanceOf(typeof(SerializationBinderAdapter), binder);
  1868. Assert.AreEqual(typeof(string), binder.BindToType(null, null));
  1869. }
  1870. public class FancyBinder : ISerializationBinder
  1871. {
  1872. private static readonly string Annotate = new string(':', 3);
  1873. public void BindToName(Type serializedType, out string assemblyName, out string typeName)
  1874. {
  1875. assemblyName = string.Format("FancyAssemblyName=>{0}", Assembly.GetAssembly(serializedType)?.GetName().Name);
  1876. typeName = string.Format("{0}{1}{0}", Annotate, serializedType.Name);
  1877. }
  1878. public Type BindToType(string assemblyName, string typeName)
  1879. {
  1880. return null;
  1881. }
  1882. }
  1883. #pragma warning disable CS0618 // Type or member is obsolete
  1884. public class OldBinder : SerializationBinder
  1885. {
  1886. public override Type BindToType(string assemblyName, string typeName)
  1887. {
  1888. return typeof(string);
  1889. }
  1890. }
  1891. #pragma warning restore CS0618 // Type or member is obsolete
  1892. #endif
  1893. }
  1894. public struct Message2
  1895. {
  1896. public string Value { get; }
  1897. [JsonConstructor]
  1898. public Message2(string value)
  1899. {
  1900. if (value == null) throw new ArgumentNullException(nameof(value));
  1901. Value = value;
  1902. }
  1903. }
  1904. public class ObjectWithOptionalMessage
  1905. {
  1906. public Message2? Message { get; }
  1907. public ObjectWithOptionalMessage(Message2? message)
  1908. {
  1909. Message = message;
  1910. }
  1911. }
  1912. public class DataType
  1913. {
  1914. public DataType()
  1915. {
  1916. Rows = new Dictionary<string, IEnumerable<IMyInterfaceType>>();
  1917. }
  1918. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto)]
  1919. public Dictionary<string, IEnumerable<IMyInterfaceType>> Rows { get; private set; }
  1920. }
  1921. public interface IMyInterfaceType
  1922. {
  1923. string SomeProperty { get; set; }
  1924. }
  1925. public class MyInterfaceImplementationType : IMyInterfaceType
  1926. {
  1927. public string SomeProperty { get; set; }
  1928. }
  1929. #if !(DNXCORE50)
  1930. public class ParentParent
  1931. {
  1932. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)]
  1933. public MyParent ParentProp { get; set; }
  1934. }
  1935. [Serializable]
  1936. public class MyParent : ISerializable
  1937. {
  1938. public ISomeBase Child { get; internal set; }
  1939. public MyParent(SerializationInfo info, StreamingContext context)
  1940. {
  1941. Child = (ISomeBase)info.GetValue("c", typeof(ISomeBase));
  1942. }
  1943. public MyParent()
  1944. {
  1945. }
  1946. void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
  1947. {
  1948. info.AddValue("c", Child);
  1949. }
  1950. }
  1951. public class MyChild : ISomeBase
  1952. {
  1953. [JsonProperty("p")]
  1954. public String MyProperty { get; internal set; }
  1955. }
  1956. public class MyChildList : List<string>, ISomeBase
  1957. {
  1958. }
  1959. public interface ISomeBase
  1960. {
  1961. }
  1962. #endif
  1963. public class Message
  1964. {
  1965. public string Address { get; set; }
  1966. [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
  1967. public object Body { get; set; }
  1968. }
  1969. public class SearchDetails
  1970. {
  1971. public string Query { get; set; }
  1972. public string Language { get; set; }
  1973. }
  1974. public class Customer
  1975. {
  1976. public string Name { get; set; }
  1977. }
  1978. public class Purchase
  1979. {
  1980. public string ProductName { get; set; }
  1981. public decimal Price { get; set; }
  1982. public int Quantity { get; set; }
  1983. }
  1984. #if !(DNXCORE50)
  1985. public class SerializableWrapper
  1986. {
  1987. public object Content { get; set; }
  1988. public override bool Equals(object obj)
  1989. {
  1990. SerializableWrapper w = obj as SerializableWrapper;
  1991. if (w == null)
  1992. {
  1993. return false;
  1994. }
  1995. return Equals(w.Content, Content);
  1996. }
  1997. public override int GetHashCode()
  1998. {
  1999. if (Content == null)
  2000. {
  2001. return 0;
  2002. }
  2003. return Content.GetHashCode();
  2004. }
  2005. }
  2006. public interface IExample
  2007. : ISerializable
  2008. {
  2009. String Name { get; }
  2010. }
  2011. [Serializable]
  2012. public class Example
  2013. : IExample
  2014. {
  2015. public Example(String name)
  2016. {
  2017. Name = name;
  2018. }
  2019. protected Example(SerializationInfo info, StreamingContext context)
  2020. {
  2021. Name = info.GetString("name");
  2022. }
  2023. public void GetObjectData(SerializationInfo info, StreamingContext context)
  2024. {
  2025. info.AddValue("name", Name);
  2026. }
  2027. public String Name { get; set; }
  2028. public override bool Equals(object obj)
  2029. {
  2030. if (obj == null)
  2031. {
  2032. return false;
  2033. }
  2034. if (ReferenceEquals(this, obj))
  2035. {
  2036. return true;
  2037. }
  2038. if (obj is IExample)
  2039. {
  2040. return Name.Equals(((IExample)obj).Name);
  2041. }
  2042. else
  2043. {
  2044. return false;
  2045. }
  2046. }
  2047. public override int GetHashCode()
  2048. {
  2049. if (Name == null)
  2050. {
  2051. return 0;
  2052. }
  2053. return Name.GetHashCode();
  2054. }
  2055. }
  2056. #endif
  2057. public class PropertyItemTypeNameHandlingObject
  2058. {
  2059. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  2060. public TypeNameHandlingTestObject Data { get; set; }
  2061. }
  2062. #if !(NET35 || NET20 || PORTABLE40)
  2063. public class PropertyItemTypeNameHandlingDynamic
  2064. {
  2065. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  2066. public DynamicDictionary Data { get; set; }
  2067. }
  2068. #endif
  2069. public class TypeNameHandlingTestObject
  2070. {
  2071. public object Prop1 { get; set; }
  2072. public object Prop2 { get; set; }
  2073. public object Prop3 { get; set; }
  2074. public object Prop4 { get; set; }
  2075. }
  2076. public class PropertyItemTypeNameHandlingDictionary
  2077. {
  2078. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  2079. public IDictionary<string, object> Data { get; set; }
  2080. }
  2081. public class PropertyItemTypeNameHandling
  2082. {
  2083. [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)]
  2084. public IList<object> Data { get; set; }
  2085. }
  2086. [JsonArray(ItemTypeNameHandling = TypeNameHandling.All)]
  2087. public class TypeNameList<T> : List<T>
  2088. {
  2089. }
  2090. [JsonDictionary(ItemTypeNameHandling = TypeNameHandling.All)]
  2091. public class TypeNameDictionary<T> : Dictionary<string, T>
  2092. {
  2093. }
  2094. [JsonObject(ItemTypeNameHandling = TypeNameHandling.All)]
  2095. public class TypeNameObject
  2096. {
  2097. public object Object1 { get; set; }
  2098. public object Object2 { get; set; }
  2099. [JsonProperty(TypeNameHandling = TypeNameHandling.None)]
  2100. public object ObjectNotHandled { get; set; }
  2101. public string String { get; set; }
  2102. public int Integer { get; set; }
  2103. }
  2104. #if !NET20
  2105. [DataContract]
  2106. public class GroupingInfo
  2107. {
  2108. [DataMember]
  2109. public ApplicationItemKeys ItemIdentifier { get; set; }
  2110. public GroupingInfo()
  2111. {
  2112. ItemIdentifier = new ApplicationItemKeys();
  2113. }
  2114. }
  2115. [DataContract]
  2116. public class ApplicationItemKeys
  2117. {
  2118. [DataMember]
  2119. public int ID { get; set; }
  2120. [DataMember]
  2121. public string Name { get; set; }
  2122. }
  2123. [DataContract]
  2124. public class ReportItemKeys : ApplicationItemKeys
  2125. {
  2126. protected ulong _wantedUnit;
  2127. [DataMember]
  2128. public ulong WantedUnitID
  2129. {
  2130. get { return _wantedUnit; }
  2131. set { _wantedUnit = value; }
  2132. }
  2133. }
  2134. #endif
  2135. }
  2136. #endif