PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/NServiceBus.Core.Tests/Serializers/XML/SerializerTests.cs

https://github.com/skyuni/NServiceBus
C# | 1045 lines | 845 code | 200 blank | 0 comment | 15 complexity | e40b809fdf43c9caa781b1471b768d18 MD5 | raw file
  1. namespace NServiceBus.Serializers.XML.Test
  2. {
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Net.Mail;
  11. using System.Runtime.Serialization;
  12. using System.Text;
  13. using System.Threading;
  14. using System.Xml;
  15. using System.Xml.Linq;
  16. using A;
  17. using B;
  18. using MessageInterfaces;
  19. using MessageInterfaces.MessageMapper.Reflection;
  20. using NUnit.Framework;
  21. using Serialization;
  22. [TestFixture]
  23. public class SerializerTests
  24. {
  25. private int number = 1;
  26. private int numberOfIterations = 100;
  27. [Test]
  28. public void SerializeInvalidCharacters()
  29. {
  30. IMessageMapper mapper = new MessageMapper();
  31. var serializer = SerializerFactory.Create<MessageWithInvalidCharacter>();
  32. var msg = mapper.CreateInstance<MessageWithInvalidCharacter>();
  33. var sb = new StringBuilder();
  34. sb.Append("Hello");
  35. sb.Append((char)0x1C);
  36. sb.Append("John");
  37. msg.Special = sb.ToString();
  38. using (var stream = new MemoryStream())
  39. {
  40. serializer.Serialize(msg, stream);
  41. stream.Position = 0;
  42. var msgArray = serializer.Deserialize(stream);
  43. var m = (MessageWithInvalidCharacter)msgArray[0];
  44. Assert.AreEqual(sb.ToString(), m.Special);
  45. }
  46. }
  47. [Test, Ignore("ArrayList is not supported")]
  48. public void Should_deserialize_arrayList()
  49. {
  50. var expected = new ArrayList
  51. {
  52. "Value1",
  53. "Value2",
  54. "Value3",
  55. };
  56. var result = ExecuteSerializer.ForMessage<MessageWithArrayList>(m3 => m3.ArrayList = expected);
  57. CollectionAssert.AreEqual(expected, result.ArrayList);
  58. }
  59. [Test, Ignore("Hashtable is not supported")]
  60. public void Should_deserialize_hashtable()
  61. {
  62. var expected = new Hashtable
  63. {
  64. {"Key1", "Value1"},
  65. {"Key2", "Value2"},
  66. {"Key3", "Value3"},
  67. };
  68. var result = ExecuteSerializer.ForMessage<MessageWithHashtable>(m3 => m3.Hashtable = expected);
  69. CollectionAssert.AreEqual(expected, result.Hashtable);
  70. }
  71. [Test]
  72. public void Should_deserialize_multiple_messages_from_different_namespaces()
  73. {
  74. var xml = @"<?xml version=""1.0"" ?>
  75. <Messages
  76. xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
  77. xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
  78. xmlns=""http://tempuri.net/NServiceBus.Serializers.XML.Test.A""
  79. xmlns:q1=""http://tempuri.net/NServiceBus.Serializers.XML.Test.B"">
  80. <Command1>
  81. <Id>1eb17e5d-8573-49af-a5cb-76b4a602bb79</Id>
  82. </Command1>
  83. <q1:Command2>
  84. <Id>ad3b5a84-6cf1-4376-aa2d-058b1120c12f</Id>
  85. </q1:Command2>
  86. </Messages>
  87. ";
  88. using (var stream = new MemoryStream())
  89. {
  90. var writer = new StreamWriter(stream);
  91. writer.Write(xml);
  92. writer.Flush();
  93. stream.Position = 0;
  94. var msgArray = SerializerFactory.Create(typeof(Command1), typeof(Command2)).Deserialize(stream);
  95. Assert.AreEqual(typeof(Command1), msgArray[0].GetType());
  96. Assert.AreEqual(typeof(Command2), msgArray[1].GetType());
  97. }
  98. }
  99. [Test]
  100. public void Should_deserialize_a_single_message_where_root_element_is_the_typeName()
  101. {
  102. using (var stream = new MemoryStream())
  103. {
  104. var writer = new StreamWriter(stream);
  105. writer.WriteLine("<NServiceBus.Serializers.XML.Test.MessageWithDouble><Double>23.4</Double></NServiceBus.Serializers.XML.Test.MessageWithDouble>");
  106. writer.Flush();
  107. stream.Position = 0;
  108. var msgArray = SerializerFactory.Create(typeof(MessageWithDouble)).Deserialize(stream);
  109. Assert.AreEqual(typeof(MessageWithDouble), msgArray[0].GetType());
  110. }
  111. }
  112. [Test]
  113. public void Should_be_able_to_serialize_single_message_without_wrapping_element()
  114. {
  115. Serializer.ForMessage<EmptyMessage>(new EmptyMessage())
  116. .AssertResultingXml(d=> d.DocumentElement.Name == "EmptyMessage","Root should be message typename");
  117. }
  118. [Test]
  119. public void Should_be_able_to_serialize_single_message_without_wrapping_xml_raw_data()
  120. {
  121. const string XmlElement = "<SomeClass xmlns=\"http://nservicebus.com\"><SomeProperty value=\"Bar\" /></SomeClass>";
  122. const string XmlDocument = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + XmlElement;
  123. var messageWithXDocument = new MessageWithXDocument { Document = XDocument.Load(new StringReader(XmlDocument)) };
  124. var messageWithXElement = new MessageWithXElement { Document = XElement.Load(new StringReader(XmlElement)) };
  125. Serializer.ForMessage<MessageWithXDocument>(messageWithXDocument, s =>
  126. { s.SkipWrappingRawXml = true; })
  127. .AssertResultingXml(d => d.DocumentElement.ChildNodes[0].FirstChild.Name != "Document", "Property name should not be available");
  128. Serializer.ForMessage<MessageWithXElement>(messageWithXElement, s =>
  129. { s.SkipWrappingRawXml = true; })
  130. .AssertResultingXml(d => d.DocumentElement.ChildNodes[0].FirstChild.Name != "Document", "Property name should not be available");
  131. }
  132. [Test]
  133. public void Should_be_able_to_deserialize_messages_which_xml_raw_data_root_element_matches_property_name()
  134. {
  135. const string XmlElement = "<Document xmlns=\"http://nservicebus.com\"><SomeProperty value=\"Bar\" /></Document>";
  136. const string XmlDocument = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + XmlElement;
  137. var messageWithXDocument = new MessageWithXDocument { Document = XDocument.Load(new StringReader(XmlDocument)) };
  138. var messageWithXElement = new MessageWithXElement { Document = XElement.Load(new StringReader(XmlElement)) };
  139. var serializer = SerializerFactory.Create<MessageWithXDocument>();
  140. serializer.SkipWrappingRawXml = true;
  141. using (var stream = new MemoryStream())
  142. {
  143. serializer.Serialize(messageWithXDocument, stream);
  144. stream.Position = 0;
  145. serializer = SerializerFactory.Create(typeof (MessageWithXDocument));
  146. serializer.SkipWrappingRawXml = true;
  147. var msg = serializer.Deserialize(stream).Cast<MessageWithXDocument>().Single();
  148. Assert.NotNull(msg.Document);
  149. Assert.AreEqual("Document", msg.Document.Root.Name.LocalName);
  150. }
  151. serializer = SerializerFactory.Create<MessageWithXElement>();
  152. serializer.SkipWrappingRawXml = true;
  153. using (var stream = new MemoryStream())
  154. {
  155. serializer.Serialize(messageWithXElement, stream);
  156. stream.Position = 0;
  157. serializer = SerializerFactory.Create(typeof (MessageWithXElement));
  158. serializer.SkipWrappingRawXml = true;
  159. var msg = serializer.Deserialize(stream).Cast<MessageWithXElement>().Single();
  160. Assert.NotNull(msg.Document);
  161. Assert.AreEqual("Document", msg.Document.Name.LocalName);
  162. }
  163. }
  164. [Test]
  165. public void Should_be_able_to_serialize_single_message_with_default_namespaces_and_then_deserialize()
  166. {
  167. var serializer = SerializerFactory.Create<MessageWithDouble>();
  168. var msg = new MessageWithDouble();
  169. using (var stream = new MemoryStream())
  170. {
  171. serializer.Serialize(msg, stream);
  172. stream.Position = 0;
  173. var msgArray = SerializerFactory.Create(typeof(MessageWithDouble)).Deserialize(stream);
  174. Assert.AreEqual(typeof(MessageWithDouble), msgArray[0].GetType());
  175. }
  176. }
  177. [Test]
  178. public void Should_be_able_to_serialize_single_message_with_default_namespaces()
  179. {
  180. var serializer = SerializerFactory.Create<EmptyMessage>();
  181. var msg = new EmptyMessage();
  182. var expected = @"<EmptyMessage xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://tempuri.net/NServiceBus.Serializers.XML.Test"">";
  183. AssertSerializedEquals(serializer, msg, expected);
  184. }
  185. [Test]
  186. public void Should_be_able_to_serialize_single_message_with_specified_namespaces()
  187. {
  188. var serializer = SerializerFactory.Create<EmptyMessage>();
  189. serializer.Namespace = "http://super.com";
  190. var msg = new EmptyMessage();
  191. var expected = @"<EmptyMessage xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://super.com/NServiceBus.Serializers.XML.Test"">";
  192. AssertSerializedEquals(serializer, msg, expected);
  193. }
  194. [Test]
  195. public void Should_be_able_to_serialize_single_message_with_specified_namespace_with_trailing_forward_slashes()
  196. {
  197. var serializer = SerializerFactory.Create<EmptyMessage>();
  198. serializer.Namespace = "http://super.com///";
  199. var msg = new EmptyMessage();
  200. var expected = @"<EmptyMessage xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://super.com/NServiceBus.Serializers.XML.Test"">";
  201. AssertSerializedEquals(serializer, msg, expected);
  202. }
  203. static void AssertSerializedEquals(IMessageSerializer serializer, IMessage msg, string expected)
  204. {
  205. using (var stream = new MemoryStream())
  206. {
  207. serializer.Serialize(msg, stream);
  208. stream.Position = 0;
  209. string result;
  210. using (var reader = new StreamReader(stream))
  211. {
  212. reader.ReadLine();
  213. result = reader.ReadLine();
  214. }
  215. Assert.AreEqual(expected, result);
  216. }
  217. }
  218. [Test]
  219. public void Should_deserialize_a_single_message_with_typeName_passed_in_externally()
  220. {
  221. using (var stream = new MemoryStream())
  222. {
  223. var writer = new StreamWriter(stream);
  224. writer.WriteLine("<WhatEver><Double>23.4</Double></WhatEver>");
  225. writer.Flush();
  226. stream.Position = 0;
  227. var msgArray = SerializerFactory.Create(typeof(MessageWithDouble)).Deserialize(stream, new[] { typeof(MessageWithDouble) });
  228. Assert.AreEqual(typeof(MessageWithDouble), msgArray[0].GetType());
  229. }
  230. }
  231. [Test]
  232. public void Should_deserialize_a_batched_messages_with_typeName_passed_in_externally()
  233. {
  234. using (var stream = new MemoryStream())
  235. {
  236. var writer = new StreamWriter(stream);
  237. writer.WriteLine("<Messages><WhatEver><Double>23.4</Double></WhatEver><TheEmptyMessage></TheEmptyMessage></Messages>");
  238. writer.Flush();
  239. stream.Position = 0;
  240. var msgArray = SerializerFactory.Create(typeof(MessageWithDouble),typeof(EmptyMessage))
  241. .Deserialize(stream, new[] { typeof(MessageWithDouble), typeof(EmptyMessage) });
  242. Assert.AreEqual(23.4, ((MessageWithDouble)msgArray[0]).Double);
  243. Assert.AreEqual(typeof(EmptyMessage), msgArray[1].GetType());
  244. }
  245. }
  246. [Test]
  247. public void TestMultipleInterfacesDuplicatedProperty()
  248. {
  249. IMessageMapper mapper = new MessageMapper();
  250. var serializer = SerializerFactory.Create<IThird>();
  251. var msgBeforeSerialization = mapper.CreateInstance<IThird>(x => x.FirstName = "Danny");
  252. var count = 0;
  253. using (var stream = new MemoryStream())
  254. {
  255. serializer.Serialize(msgBeforeSerialization, stream);
  256. stream.Position = 0;
  257. var reader = XmlReader.Create(stream);
  258. while (reader.Read())
  259. if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "FirstName"))
  260. count++;
  261. }
  262. Assert.AreEqual(count, 1);
  263. }
  264. [Test]
  265. public void Generic_properties_should_be_supported()
  266. {
  267. var result = ExecuteSerializer.ForMessage<MessageWithGenericProperty>(m =>
  268. {
  269. m.GenericProperty =
  270. new GenericProperty<string>("test") { WhatEver = "a property" };
  271. });
  272. Assert.AreEqual("a property", result.GenericProperty.WhatEver);
  273. }
  274. [Test]
  275. public void Culture()
  276. {
  277. var serializer = SerializerFactory.Create<MessageWithDouble>();
  278. var val = 65.36;
  279. var msg = new MessageWithDouble { Double = val };
  280. Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
  281. var stream = new MemoryStream();
  282. serializer.Serialize(msg, stream);
  283. Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
  284. stream.Position = 0;
  285. var msgArray = serializer.Deserialize(stream);
  286. var m = (MessageWithDouble)msgArray[0];
  287. Assert.AreEqual(val, m.Double);
  288. stream.Dispose();
  289. }
  290. [Test]
  291. public void Comparison()
  292. {
  293. TestInterfaces();
  294. TestDataContractSerializer();
  295. }
  296. [Test]
  297. public void TestInterfaces()
  298. {
  299. IMessageMapper mapper = new MessageMapper();
  300. var serializer = SerializerFactory.Create<IM2>();
  301. var o = mapper.CreateInstance<IM2>();
  302. o.Id = Guid.NewGuid();
  303. o.Age = 10;
  304. o.Address = Guid.NewGuid().ToString();
  305. o.Int = 7;
  306. o.Name = "udi";
  307. o.Uri = new Uri("http://www.UdiDahan.com/");
  308. o.Risk = new Risk { Percent = 0.15D, Annum = true, Accuracy = 0.314M };
  309. o.Some = SomeEnum.B;
  310. o.Start = DateTime.Now;
  311. o.Duration = TimeSpan.Parse("-01:15:27.123");
  312. o.Offset = DateTimeOffset.Now;
  313. o.Lookup = new MyDictionary();
  314. o.Lookup["1"] = "1";
  315. o.Foos = new Dictionary<string, List<Foo>>();
  316. o.Foos["foo1"] = new List<Foo>(new[] { new Foo { Name = "1", Title = "1" }, new Foo { Name = "2", Title = "2" } });
  317. o.Data = new byte[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
  318. o.SomeStrings = new List<string> { "a", "b", "c" };
  319. o.ArrayFoos = new[] { new Foo { Name = "FooArray1", Title = "Mr." }, new Foo { Name = "FooAray2", Title = "Mrs" } };
  320. o.Bars = new[] { new Bar { Name = "Bar1", Length = 1 }, new Bar { Name = "BAr2", Length = 5 } };
  321. o.NaturalNumbers = new HashSet<int>(new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
  322. o.Developers = new HashSet<string>(new[] { "Udi Dahan", "Andreas Ohlund", "Matt Burton", "Jonathan Oliver et al" });
  323. o.Parent = mapper.CreateInstance<IM1>();
  324. o.Parent.Name = "udi";
  325. o.Parent.Age = 10;
  326. o.Parent.Address = Guid.NewGuid().ToString();
  327. o.Parent.Int = 7;
  328. o.Parent.Name = "-1";
  329. o.Parent.Risk = new Risk { Percent = 0.15D, Annum = true, Accuracy = 0.314M };
  330. o.Names = new List<IM1>();
  331. for (var i = 0; i < number; i++)
  332. {
  333. var m1 = mapper.CreateInstance<IM1>();
  334. o.Names.Add(m1);
  335. m1.Age = 10;
  336. m1.Address = Guid.NewGuid().ToString();
  337. m1.Int = 7;
  338. m1.Name = i.ToString();
  339. m1.Risk = new Risk { Percent = 0.15D, Annum = true, Accuracy = 0.314M };
  340. }
  341. o.MoreNames = o.Names.ToArray();
  342. Time(o, serializer);
  343. }
  344. [Test]
  345. public void TestDataContractSerializer()
  346. {
  347. var o = CreateM2();
  348. var messages = new IMessage[] { o };
  349. var dataContractSerializer = new DataContractSerializer(typeof(ArrayList), new[] { typeof(M2), typeof(SomeEnum), typeof(M1), typeof(Risk), typeof(List<M1>) });
  350. var sw = new Stopwatch();
  351. sw.Start();
  352. var xmlWriterSettings = new XmlWriterSettings
  353. {
  354. OmitXmlDeclaration = false
  355. };
  356. var xmlReaderSettings = new XmlReaderSettings
  357. {
  358. IgnoreProcessingInstructions = true,
  359. ValidationType = ValidationType.None,
  360. IgnoreWhitespace = true,
  361. CheckCharacters = false,
  362. ConformanceLevel = ConformanceLevel.Auto
  363. };
  364. for (var i = 0; i < numberOfIterations; i++)
  365. using (var stream = new MemoryStream())
  366. DataContractSerialize(xmlWriterSettings, dataContractSerializer, messages, stream);
  367. sw.Stop();
  368. Debug.WriteLine("serialization " + sw.Elapsed);
  369. sw.Reset();
  370. File.Delete("a.xml");
  371. using (var fs = File.Open("a.xml", FileMode.OpenOrCreate))
  372. DataContractSerialize(xmlWriterSettings, dataContractSerializer, messages, fs);
  373. var s = new MemoryStream();
  374. DataContractSerialize(xmlWriterSettings, dataContractSerializer, messages, s);
  375. var buffer = s.GetBuffer();
  376. s.Dispose();
  377. sw.Start();
  378. for (var i = 0; i < numberOfIterations; i++)
  379. using (var reader = XmlReader.Create(new MemoryStream(buffer), xmlReaderSettings))
  380. dataContractSerializer.ReadObject(reader);
  381. sw.Stop();
  382. Debug.WriteLine("deserializing: " + sw.Elapsed);
  383. }
  384. [Test]
  385. public void SerializeLists()
  386. {
  387. IMessageMapper mapper = new MessageMapper();
  388. var serializer = SerializerFactory.Create<MessageWithList>();
  389. var msg = mapper.CreateInstance<MessageWithList>();
  390. msg.Items = new List<MessageWithListItem> { new MessageWithListItem { Data = "Hello" } };
  391. using (var stream = new MemoryStream())
  392. {
  393. serializer.Serialize(msg, stream);
  394. stream.Position = 0;
  395. var msgArray = serializer.Deserialize(stream);
  396. var m = (MessageWithList)msgArray[0];
  397. Assert.AreEqual("Hello", m.Items.First().Data);
  398. }
  399. }
  400. [Test]
  401. public void SerializeClosedGenericListsInAlternateNamespace()
  402. {
  403. IMessageMapper mapper = new MessageMapper();
  404. var serializer = SerializerFactory.Create<MessageWithClosedListInAlternateNamespace>();
  405. var msg = mapper.CreateInstance<MessageWithClosedListInAlternateNamespace>();
  406. msg.Items = new AlternateNamespace.AlternateItemList { new AlternateNamespace.MessageWithListItemAlternate { Data = "Hello" } };
  407. using (var stream = new MemoryStream())
  408. {
  409. serializer.Serialize(msg, stream);
  410. stream.Position = 0;
  411. var msgArray = serializer.Deserialize(stream);
  412. var m = (MessageWithClosedListInAlternateNamespace)msgArray[0];
  413. Assert.AreEqual("Hello", m.Items.First().Data);
  414. }
  415. }
  416. [Test]
  417. public void SerializeClosedGenericListsInAlternateNamespaceMultipleIEnumerableImplementations()
  418. {
  419. IMessageMapper mapper = new MessageMapper();
  420. var serializer = SerializerFactory.Create<MessageWithClosedListInAlternateNamespaceMultipleIEnumerableImplementations>();
  421. var msg = mapper.CreateInstance<MessageWithClosedListInAlternateNamespaceMultipleIEnumerableImplementations>();
  422. msg.Items = new AlternateNamespace.AlternateItemListMultipleIEnumerableImplementations { new AlternateNamespace.MessageWithListItemAlternate { Data = "Hello" } };
  423. using (var stream = new MemoryStream())
  424. {
  425. serializer.Serialize(msg, stream);
  426. stream.Position = 0;
  427. var msgArray = serializer.Deserialize(stream);
  428. var m = (MessageWithClosedListInAlternateNamespaceMultipleIEnumerableImplementations)msgArray[0];
  429. Assert.AreEqual("Hello", m.Items.First<AlternateNamespace.MessageWithListItemAlternate>().Data);
  430. }
  431. }
  432. [Test]
  433. public void SerializeClosedGenericListsInAlternateNamespaceMultipleIListImplementations()
  434. {
  435. IMessageMapper mapper = new MessageMapper();
  436. var serializer = SerializerFactory.Create<MessageWithClosedListInAlternateNamespaceMultipleIListImplementations>();
  437. var msg = mapper.CreateInstance<MessageWithClosedListInAlternateNamespaceMultipleIListImplementations>();
  438. msg.Items = new AlternateNamespace.AlternateItemListMultipleIListImplementations { new AlternateNamespace.MessageWithListItemAlternate { Data = "Hello" } };
  439. using (var stream = new MemoryStream())
  440. {
  441. serializer.Serialize(msg, stream);
  442. stream.Position = 0;
  443. var msgArray = serializer.Deserialize(stream);
  444. var m = (MessageWithClosedListInAlternateNamespaceMultipleIListImplementations)msgArray[0];
  445. Assert.AreEqual("Hello", m.Items.First<AlternateNamespace.MessageWithListItemAlternate>().Data);
  446. }
  447. }
  448. [Test]
  449. public void SerializeClosedGenericListsInSameNamespace()
  450. {
  451. IMessageMapper mapper = new MessageMapper();
  452. var serializer = SerializerFactory.Create<MessageWithClosedList>();
  453. var msg = mapper.CreateInstance<MessageWithClosedList>();
  454. msg.Items = new ItemList { new MessageWithListItem { Data = "Hello" } };
  455. using (var stream = new MemoryStream())
  456. {
  457. serializer.Serialize(msg, stream);
  458. stream.Position = 0;
  459. var msgArray = serializer.Deserialize(stream);
  460. var m = (MessageWithClosedList)msgArray[0];
  461. Assert.AreEqual("Hello", m.Items.First().Data);
  462. }
  463. }
  464. [Test]
  465. public void SerializeEmptyLists()
  466. {
  467. IMessageMapper mapper = new MessageMapper();
  468. var serializer = SerializerFactory.Create<MessageWithList>();
  469. var msg = mapper.CreateInstance<MessageWithList>();
  470. msg.Items = new List<MessageWithListItem>();
  471. using (var stream = new MemoryStream())
  472. {
  473. serializer.Serialize(msg, stream);
  474. stream.Position = 0;
  475. var msgArray = serializer.Deserialize(stream);
  476. var m = (MessageWithList)msgArray[0];
  477. Assert.IsEmpty(m.Items);
  478. }
  479. }
  480. private void DataContractSerialize(XmlWriterSettings xmlWriterSettings, DataContractSerializer dataContractSerializer, IMessage[] messages, Stream stream)
  481. {
  482. var o = new ArrayList(messages);
  483. using (var xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
  484. {
  485. dataContractSerializer.WriteStartObject(xmlWriter, o);
  486. dataContractSerializer.WriteObjectContent(xmlWriter, o);
  487. dataContractSerializer.WriteEndObject(xmlWriter);
  488. }
  489. }
  490. M2 CreateM2()
  491. {
  492. var o = new M2
  493. {
  494. Id = Guid.NewGuid(),
  495. Age = 10,
  496. Address = Guid.NewGuid().ToString(),
  497. Int = 7,
  498. Name = "udi",
  499. Risk = new Risk
  500. {
  501. Percent = 0.15D,
  502. Annum = true,
  503. Accuracy = 0.314M
  504. },
  505. Some = SomeEnum.B,
  506. Start = DateTime.Now,
  507. Duration = TimeSpan.Parse("-01:15:27.123"),
  508. Offset = DateTimeOffset.Now,
  509. Parent = new M1
  510. {
  511. Age = 10,
  512. Address = Guid.NewGuid().ToString(), Int = 7,
  513. Name = "-1",
  514. Risk = new Risk
  515. {
  516. Percent = 0.15D,
  517. Annum = true,
  518. Accuracy = 0.314M
  519. }
  520. },
  521. Names = new List<M1>()
  522. };
  523. for (var i = 0; i < number; i++)
  524. {
  525. var m1 = new M1();
  526. o.Names.Add(m1);
  527. m1.Age = 10;
  528. m1.Address = Guid.NewGuid().ToString();
  529. m1.Int = 7;
  530. m1.Name = i.ToString();
  531. m1.Risk = new Risk
  532. {
  533. Percent = 0.15D,
  534. Annum = true,
  535. Accuracy = 0.314M
  536. };
  537. }
  538. o.MoreNames = o.Names.ToArray();
  539. return o;
  540. }
  541. private void Time(object message, IMessageSerializer serializer)
  542. {
  543. var watch = new Stopwatch();
  544. watch.Start();
  545. for (var i = 0; i < numberOfIterations; i++)
  546. using (var stream = new MemoryStream())
  547. serializer.Serialize(message, stream);
  548. watch.Stop();
  549. Debug.WriteLine("Serializing: " + watch.Elapsed);
  550. watch.Reset();
  551. var s = new MemoryStream();
  552. serializer.Serialize(message, s);
  553. var buffer = s.GetBuffer();
  554. s.Dispose();
  555. watch.Start();
  556. for (var i = 0; i < numberOfIterations; i++)
  557. using (var forDeserializing = new MemoryStream(buffer))
  558. serializer.Deserialize(forDeserializing);
  559. watch.Stop();
  560. Debug.WriteLine("Deserializing: " + watch.Elapsed);
  561. }
  562. [Test]
  563. public void NestedObjectWithNullPropertiesShouldBeSerialized()
  564. {
  565. var result = ExecuteSerializer.ForMessage<MessageWithNestedObject>(m =>
  566. {
  567. m.NestedObject = new MessageWithNullProperty();
  568. });
  569. Assert.IsNotNull(result.NestedObject);
  570. }
  571. [Test]
  572. public void Messages_with_generic_properties_closing_nullables_should_be_supported()
  573. {
  574. var theTime = DateTime.Now;
  575. var result = ExecuteSerializer.ForMessage<MessageWithGenericPropClosingNullable>(
  576. m =>
  577. {
  578. m.GenericNullable = new GenericPropertyWithNullable<DateTime?> { TheType = theTime };
  579. m.Whatever = "fdsfsdfsd";
  580. });
  581. Assert.IsNotNull(result.GenericNullable.TheType == theTime);
  582. }
  583. [Test]
  584. public void When_Using_A_Dictionary_With_An_object_As_Key_should_throw()
  585. {
  586. Assert.Throws<NotSupportedException>(() => SerializerFactory.Create<MessageWithDictionaryWithAnObjectAsKey>());
  587. }
  588. [Test]
  589. public void When_Using_A_Dictionary_With_An_Object_As_Value_should_throw()
  590. {
  591. Assert.Throws<NotSupportedException>(() => SerializerFactory.Create<MessageWithDictionaryWithAnObjectAsValue>());
  592. }
  593. [Test, Ignore("We're not supporting this type")]
  594. public void System_classes_with_non_default_constructors_should_be_supported()
  595. {
  596. var message = new MailMessage("from@gmail.com", "to@hotmail.com")
  597. {
  598. Subject = "Testing the NSB email support",
  599. Body = "Hello",
  600. };
  601. var result = ExecuteSerializer.ForMessage<MessageWithSystemClassAsProperty>(
  602. m =>
  603. {
  604. m.MailMessage = message;
  605. });
  606. Assert.IsNotNull(result.MailMessage);
  607. Assert.AreEqual("from@gmail.com", result.MailMessage.From.Address);
  608. Assert.AreEqual(message.To.First(), result.MailMessage.To.First());
  609. Assert.AreEqual(message.BodyEncoding.CodePage, result.MailMessage.BodyEncoding.CodePage);
  610. Assert.AreEqual(message.BodyEncoding.EncoderFallback.MaxCharCount, result.MailMessage.BodyEncoding.EncoderFallback.MaxCharCount);
  611. }
  612. [Test, Ignore("We're currently not supporting polymorphic properties")]
  613. public void Messages_with_polymorphic_properties_should_be_supported()
  614. {
  615. var message = new PolyMessage
  616. {
  617. BaseType = new ChildOfBase
  618. {
  619. BaseTypeProp = "base",
  620. ChildProp = "Child"
  621. }
  622. };
  623. var result = ExecuteSerializer.ForMessage<PolyMessage>(message);
  624. Assert.AreEqual(message.BaseType.BaseTypeProp, result.BaseType.BaseTypeProp);
  625. Assert.AreEqual(((ChildOfBase)message.BaseType).ChildProp, ((ChildOfBase)result.BaseType).ChildProp);
  626. }
  627. [Test]
  628. public void When_Using_Property_WithXContainerAssignable_should_preserve_xml()
  629. {
  630. const string XmlElement = "<SomeClass xmlns=\"http://nservicebus.com\"><SomeProperty value=\"Bar\" /></SomeClass>";
  631. const string XmlDocument = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + XmlElement;
  632. var messageWithXDocument = new MessageWithXDocument { Document = XDocument.Load(new StringReader(XmlDocument)) };
  633. var messageWithXElement = new MessageWithXElement { Document = XElement.Load(new StringReader(XmlElement)) };
  634. var resultXDocument = ExecuteSerializer.ForMessage<MessageWithXDocument>(messageWithXDocument);
  635. var resultXElement = ExecuteSerializer.ForMessage<MessageWithXElement>(messageWithXElement);
  636. Assert.AreEqual(messageWithXDocument.Document.ToString(), resultXDocument.Document.ToString());
  637. Assert.AreEqual(messageWithXElement.Document.ToString(), resultXElement.Document.ToString());
  638. }
  639. [Test]
  640. public void Should_be_able_to_deserialize_many_messages_of_same_type()
  641. {
  642. var xml = @"<?xml version=""1.0"" ?>
  643. <Messages xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""http://tempuri.net/NServiceBus.Serializers.XML.Test"">
  644. <EmptyMessage>
  645. </EmptyMessage>
  646. <EmptyMessage>
  647. </EmptyMessage>
  648. <EmptyMessage>
  649. </EmptyMessage>
  650. </Messages>
  651. ";
  652. using (var stream = new MemoryStream())
  653. {
  654. var streamWriter = new StreamWriter(stream);
  655. streamWriter.Write(xml);
  656. streamWriter.Flush();
  657. stream.Position = 0;
  658. var serializer = SerializerFactory.Create<EmptyMessage>();
  659. var msgArray = serializer.Deserialize(stream, new[] { typeof(EmptyMessage) });
  660. Assert.AreEqual(3, msgArray.Length);
  661. }
  662. }
  663. }
  664. public class EmptyMessage:IMessage
  665. {
  666. }
  667. public class PolyMessage : IMessage
  668. {
  669. public BaseType BaseType { get; set; }
  670. }
  671. public class ChildOfBase : BaseType
  672. {
  673. public BaseType BaseType { get; set; }
  674. public string ChildProp { get; set; }
  675. }
  676. public class BaseType
  677. {
  678. public string BaseTypeProp { get; set; }
  679. }
  680. public class MessageWithGenericPropClosingNullable
  681. {
  682. public GenericPropertyWithNullable<DateTime?> GenericNullable { get; set; }
  683. public string Whatever { get; set; }
  684. }
  685. public class MessageWithNullProperty
  686. {
  687. public string WillBeNull { get; set; }
  688. }
  689. public class MessageWithDouble
  690. {
  691. public double Double { get; set; }
  692. }
  693. public class MessageWithGenericProperty
  694. {
  695. public GenericProperty<string> GenericProperty { get; set; }
  696. public GenericProperty<string> GenericPropertyThatIsNull { get; set; }
  697. }
  698. public class MessageWithNestedObject
  699. {
  700. public MessageWithNullProperty NestedObject { get; set; }
  701. }
  702. public class MessageWithSystemClassAsProperty
  703. {
  704. public MailMessage MailMessage { get; set; }
  705. }
  706. public class GenericPropertyWithNullable<T>
  707. {
  708. public T TheType { get; set; }
  709. }
  710. public class GenericProperty<T>
  711. {
  712. private T value;
  713. public GenericProperty(T value)
  714. {
  715. this.value = value;
  716. }
  717. public T ReadOnlyBlob
  718. {
  719. get
  720. {
  721. return value;
  722. }
  723. }
  724. public string WhatEver { get; set; }
  725. }
  726. public class MessageWithDictionaryWithAnObjectAsKey
  727. {
  728. public Dictionary<object, string> Content { get; set; }
  729. }
  730. public class MessageWithDictionaryWithAnObjectAsValue
  731. {
  732. public Dictionary<string, object> Content { get; set; }
  733. }
  734. public class MessageWithListItem
  735. {
  736. public string Data { get; set; }
  737. }
  738. public class MessageWithInvalidCharacter : IMessage
  739. {
  740. public string Special { get; set; }
  741. }
  742. public class MessageWithList : IMessage
  743. {
  744. public List<MessageWithListItem> Items { get; set; }
  745. }
  746. [Serializable]
  747. public class MessageWithHashtable : IMessage
  748. {
  749. public Hashtable Hashtable { get; set; }
  750. }
  751. [Serializable]
  752. public class MessageWithArrayList : IMessage
  753. {
  754. public ArrayList ArrayList { get; set; }
  755. }
  756. public class MessageWithClosedListInAlternateNamespace : IMessage
  757. {
  758. public AlternateNamespace.AlternateItemList Items { get; set; }
  759. }
  760. public class MessageWithClosedListInAlternateNamespaceMultipleIEnumerableImplementations : IMessage
  761. {
  762. public AlternateNamespace.AlternateItemListMultipleIEnumerableImplementations Items { get; set; }
  763. }
  764. public class MessageWithClosedListInAlternateNamespaceMultipleIListImplementations : IMessage
  765. {
  766. public AlternateNamespace.AlternateItemListMultipleIListImplementations Items { get; set; }
  767. }
  768. public class MessageWithClosedList : IMessage
  769. {
  770. public ItemList Items { get; set; }
  771. }
  772. [Serializable]
  773. public class MessageWithXDocument : IMessage
  774. {
  775. public XDocument Document { get; set; }
  776. }
  777. [Serializable]
  778. public class MessageWithXElement : IMessage
  779. {
  780. public XElement Document { get; set; }
  781. }
  782. public class ItemList : List<MessageWithListItem>
  783. {
  784. }
  785. }
  786. namespace NServiceBus.Serializers.XML.Test.AlternateNamespace
  787. {
  788. using System.Collections.Generic;
  789. using System.Linq;
  790. public class AlternateItemList : List<MessageWithListItemAlternate>
  791. {
  792. }
  793. public class MessageWithListItemAlternate
  794. {
  795. public string Data { get; set; }
  796. }
  797. public class AlternateItemListMultipleIEnumerableImplementations : List<MessageWithListItemAlternate>, IEnumerable<string>
  798. {
  799. public new IEnumerator<string> GetEnumerator()
  800. {
  801. return ToArray().Select(item => item.Data).GetEnumerator();
  802. }
  803. }
  804. public class AlternateItemListMultipleIListImplementations : List<MessageWithListItemAlternate>, IList<string>
  805. {
  806. private IList<string> stringList = new List<string>();
  807. IEnumerator<string> IEnumerable<string>.GetEnumerator()
  808. {
  809. return stringList.GetEnumerator();
  810. }
  811. void ICollection<string>.Add(string item)
  812. {
  813. stringList.Add(item);
  814. }
  815. bool ICollection<string>.Contains(string item)
  816. {
  817. return stringList.Contains(item);
  818. }
  819. void ICollection<string>.CopyTo(string[] array, int arrayIndex)
  820. {
  821. stringList.CopyTo(array, arrayIndex);
  822. }
  823. bool ICollection<string>.Remove(string item)
  824. {
  825. return stringList.Remove(item);
  826. }
  827. bool ICollection<string>.IsReadOnly
  828. {
  829. get { return stringList.IsReadOnly; }
  830. }
  831. int IList<string>.IndexOf(string item)
  832. {
  833. return stringList.IndexOf(item);
  834. }
  835. void IList<string>.Insert(int index, string item)
  836. {
  837. stringList.Insert(index, item);
  838. }
  839. string IList<string>.this[int index]
  840. {
  841. get { return stringList[index]; }
  842. set { stringList[index] = value; }
  843. }
  844. }
  845. }