{"id":629,"date":"2011-07-30T04:31:20","date_gmt":"2011-07-30T04:31:20","guid":{"rendered":"https:\/\/ibex.tech\/visualcpp\/?p=629"},"modified":"2022-02-17T06:24:04","modified_gmt":"2022-02-17T06:24:04","slug":"serialization-of-a-class","status":"publish","type":"post","link":"https:\/\/ibex.tech\/visualcpp\/serialization\/serialization-of-a-class","title":{"rendered":"Serialization Of A Class"},"content":{"rendered":"<p>\nSerialization is the process of storing the state of an object or member for storage or transfer and deserialization is the process of restoring it. &nbsp;Serialization is dead easy in .Net, as long as the same assembly is performing both the serialisation and deserialisation.\n<\/p>\n<h4>\nFormats<br \/>\n<\/h4>\n<p>\nSerialize as Binary &#8211; More compact and faster, works well with the CLR. &nbsp;The best option in terms of data typing etc, however not inteded as a long term storage solution, more of a short term pass data between processes solution.<br \/>\nSerialize as XML (SOAP) &#8211; Self describing, simplifies use when transferring between different systems.<br \/>\nXmlSerializer &#8211; Very versatile in being able to pass data between different different assemblies.\n<\/p>\n<h4>\nCreate A Class To Hold The Data You Want To Serialize<br \/>\n<\/h4>\n<h5>\nIn your .h file<br \/>\n<\/h5>\n<pre>\r\n<code>\r\n[Serializable]\r\nref class MySerializableClass\r\n{\r\npublic:\r\n\tproperty int myInt;\r\n\tproperty DateTime ^myDateTime;\r\n\tproperty array&lt;DateTime&gt; ^myArray;\r\n\tproperty String ^myString;\r\n\r\n\tMySerializableClass(int myInt, DateTime ^myDateTime, array&lt;DateTime&gt; ^myArray, String ^myString);\r\n};\r\n<\/code><\/pre>\n<h5>\nIn your .cpp file<br \/>\n<\/h5>\n<pre>\r\n<code>\r\nMySerializableClass::MySerializableClass (int myInt, DateTime ^myDateTime, array&lt;DateTime&gt; ^myArray, String ^myString)\r\n{\r\n\tthis-&gt;myInt = myInt;\r\n\tthis-&gt;myDateTime = myDateTime;\r\n\tthis-&gt;myArray = myArray;\r\n\tthis-&gt;myString = myString;\r\n}\r\n\r\n\/\/Create class containing data to be serialized\r\nMySerializableClass ^MySerializableClass1 = gcnew MySerializableClass(1, ADateTime, SomeDataTimes, &quot;Hello&quot;);\r\n<\/code><\/pre>\n<h4>\nSerialization Using BinaryFormatter<br \/>\n<\/h4>\n<pre>\r\n<code>\r\nusing namespace System::Runtime::Serialization::Formatters::Binary;\r\n\r\n\t\/\/Store To File\r\n\tFileStream ^FileStream1 = File::Create(&quot;Test.dat&quot;);\r\n\tBinaryFormatter ^BinaryFormatter1 = gcnew BinaryFormatter();\r\n\tBinaryFormatter1-&gt;Serialize(FileStream1, MySerializableClass1);\r\n\tFileStream1-&gt;Close();\r\n\r\n\t\/\/Read From File\r\n\tFileStream ^FileStream1 = File::OpenRead(&quot;Test.dat&quot;);\r\n\tBinaryFormatter ^BinaryFormatter1 = gcnew BinaryFormatter();\r\n\tFileStream1-&gt;Position = 0;\r\n\tMySerializableClass ^MySerializableClass1 = (MySerializableClass^)(BinaryFormatter1-&gt;Deserialize(FileStream1));\r\n\tFileStream1-&gt;Close();\r\n\r\n\t\/\/Store To MemoryStream\r\n\tMemoryStream ^MemoryStream1 = gcnew MemoryStream();\r\n\tBinaryFormatter ^BinaryFormatter1 = gcnew BinaryFormatter();\r\n\tBinaryFormatter1-&gt;Serialize(MemoryStream1, MySerializableClass1);\r\n\tMemoryStream1-&gt;Flush();\r\n\tMemoryStream1-&gt;Position = 0;\r\n\t\/\/To transfer the stream using TCP simply treat it as a file - send the number of bytes followed by the data so that the receiver knows how much data to receive into its memory stream before it then deserializes it.  Use MemoryStream1-&gt;ToArray()\r\n\tMemoryStream1-&gt;Close();\r\n\r\n\t\/\/Read From MemoryStream\r\n\tMemoryStream ^MemoryStream1 = gcnew MemoryStream();\r\n\tMemoryStream1-&gt;Write(RxData, 0, RxData-&gt;Length);\r\n\tBinaryFormatter ^BinaryFormatter1 = gcnew BinaryFormatter();\r\n\tMemoryStream1-&gt;Position = 0;\r\n\tMySerializableClass ^MySerializableClass1 = (MySerializableClass^)(BinaryFormatter1-&gt;Deserialize(MemoryStream1));\r\n\tMemoryStream1-&gt;Close();\r\n<\/code><\/pre>\n<h4>\nSerialization Using XML SoapFormatter<br \/>\n<\/h4>\n<pre>\r\n<code>\r\n#using &lt;system.runtime.serialization.formatters.soap.dll&gt;\r\nusing namespace System::Runtime::Serialization::Formatters::Soap;\r\n\r\n\t\/\/Store To File\r\n\tFileStream ^FileStream1 = File::Create(&quot;Test.xml&quot;);\r\n\tSoapFormatter ^SoapFormatter1 = gcnew SoapFormatter();\r\n\tSoapFormatter1-&gt;Serialize(FileStream1, MySerializableClass1);\r\n\tFileStream1-&gt;Close();\r\n\r\n\t\/\/Read From File\r\n\tFileStream ^FileStream1 = File::OpenRead(&quot;Test.xml&quot;);\r\n\tSoapFormatter ^SoapFormatter1 = gcnew SoapFormatter();\r\n\tMySerializableClass ^MySerializableClass1 = (MySerializableClass^)(SoapFormatter1-&gt;Deserialize(FileStream1));\r\n\tFileStream1-&gt;Close();\r\n<\/code><\/pre>\n<h4>\nSerialization Using&nbsp;XmlSerializer<br \/>\n<\/h4>\n<p>\nEnsure your class is defined as public and that it has a constructor with no parameters (you can have multipe constructors &#8211; just ensure one has no&nbsp;parameters passed to it &#8211;&nbsp;it can be blank)\n<\/p>\n<pre>\r\n<code>\r\nusing namespace System::Xml::Serialization;\r\n\r\n\t\/\/Store To File\r\n\tXmlSerializer ^XmlSerializer1 = gcnew XmlSerializer(MySerializableClass::typeid);\r\n\tFileStream ^FileStream1 = File::Create(&quot;Test.xml&quot;);\r\n\tXmlSerializer1-&gt;Serialize(FileStream1, MySerializableClass1);\r\n\tif (FileStream1 != nullptr)\r\n\t\tFileStream1-&gt;Close();\r\n\r\n\t\/\/Read From File\r\n\tRequestExportSerializableClass ^RequestExportSerializableClass1 = gcnew RequestExportSerializableClass();\r\n\tXmlSerializer ^XmlSerializer1 = gcnew XmlSerializer(RequestExportSerializableClass::typeid);\r\n\tFileStream ^FileStream1 = File::OpenRead(TemporaryDirectory + EXTERNAL_EXPORTER_DATA_FILE);\r\n\tRequestExportSerializableClass1 = (RequestExportSerializableClass^)XmlSerializer1-&gt;Deserialize(FileStream1);\r\n\tif (FileStream1 != nullptr)\r\n\t\tFileStream1-&gt;Close();\r\n<\/code><\/pre>\n<h5>\nIssues<br \/>\n<\/h5>\n<p>\nTimeSpan\n<\/p>\n<p style=\"margin-left: 40px;\">\nTimeSpan does nto serialaize with XmlSerializer &#8211; see <a href=\"http:\/\/connect.microsoft.com\/VisualStudio\/feedback\/details\/684819\/xml-serialization-of-timespan-doesnt-work\">here<\/a>.\n<\/p>\n<h5>\nErrors<br \/>\n<\/h5>\n<p>\n&quot;cannot be serialized because it does not have a parameterless constructor&quot;\n<\/p>\n<p style=\"margin-left: 40px;\">\nMake sure there is a constructor for your class that does not requrire any parameters (there can be more than 1 constructor with different parameter options)\n<\/p>\n<p>\n<br \/>\n&quot;is inaccessible due to its protection level. Only public types can be processed&quot;\n<\/p>\n<p style=\"margin-left: 40px;\">\nThe class must be public, e.g.<br \/>\n[Serializable]<br \/>\npublic ref class RequestExportSerializableClass<br \/>\n{\n<\/p>\n<h4>\nSerializing DateTime<br \/>\n<\/h4>\n<p>\nThis can cause problems, and sometime obscure problems. For instance using the binary formatter to format DateTime will work but if serialising a DateTime^ you can get a &quot;Binary stream &#39;1&#39; does not contain a valid BinaryHeader&quot; run time error.&nbsp; The reason is that DateTime is a value type so should always be used without the ^. When you use the caret then you get a boxed value that can&#39;t be serialized.&nbsp; Another simple solution to this problem is to convert the DateTime to a String using this:\n<\/p>\n<pre>\r\n<code>\r\n\tString ^sTemp = MyDateTime-&gt;ToString(&quot;yyyy-MM-ddTHH:mm:ss.fffffff&quot;);\r\n<\/code><\/pre>\n<p>\nand store in the class to serialise as a string. Then use Convert::ToDateTime to convert it back after deserializing.&nbsp; This also removes any local time conversion issues\n<\/p>\n<h4>\nDeserializing in a different assembly<br \/>\n<\/h4>\n<p>\nYou can serialize and desrialize from same application,&nbsp;but you can&#39;t serialize in one and deserialize in a second application quite so easily. &nbsp;This is true for binary and XML and its because serialisation is based on the types in the assembly doing the serialisation, even though the types may be the same in the deserialisation assembly.\n<\/p>\n<p>\nYou can use&nbsp;XmlSerializer as this can pass data between different assemblies (bianry and XML soap can&#39;t without jumping through complex hoops).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Serialization is the process of storing the state of an object or member for storage or transfer and deserialization is the process of restoring it. &nbsp;Serialization is dead easy in .Net, as long as the same assembly is performing both the serialisation and deserialisation. Formats Serialize as Binary &#8211; More compact and faster, works well [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[77],"tags":[],"class_list":["post-629","post","type-post","status-publish","format-standard","hentry","category-serialization"],"_links":{"self":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/629","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/comments?post=629"}],"version-history":[{"count":20,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/629\/revisions"}],"predecessor-version":[{"id":986,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/629\/revisions\/986"}],"wp:attachment":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/media?parent=629"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/categories?post=629"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/tags?post=629"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}