2016-07-08 9 views
0

Wir erstellen eine Anwendung, die unter Xamarin läuft, und wir haben einen gemeinsamen Code, der unter Android, iOS und einfach mono auf einem RaspberryPi verwendet wird. Der Code ist ein Wrapper um den System.Runtime.Serialization.Json.DataContractJsonSerializer und behandelt einfach das Konvertieren einer Klasse in und aus einer JSON-Zeichenfolge. Dieser Code funktioniert unter Windows mit .Net 4.5.2 (das ist die höchste Version, die wir auf dem PI verwenden können, auf dem mono 3.2.8 läuft).System.Runtime.Serialization.Json.DataContractJsonSerializer löst Ausnahme aus Das Argument kann nicht null sein

Das Problem ist, dass wenn wir den Serializer aufrufen, erhalten wir eine System.ArgumentNullException: Argument kann nicht null sein Parametername: rootName.

Nun, unser Objekt ist eine einfache alte Klasse, die keinen "rootName" -Knoten hat, der verdächtig aussieht, als würde es denken, wir seien Xml, nicht Json.

Wir können Newtonsoft nicht verwenden, da es sich beim Umgang mit einer komplexen Klasse um einen "Emitter" handelt, den iOS nicht zulässt, sodass wir auf den .Net Json Serializer zurückgefallen sind.

Alles funktioniert gut, wenn wir Newtonsoft (PI und Android) verwenden, aber das iOS hält uns von dieser Plattform.

Attached ist eine Konsolenanwendung, die das Problem auf dem PI originalgetreu wiedergibt. Es läuft gut in Windows und auch auf unserem Android.

Jede Hilfe wird sehr geschätzt! Vielen Dank.

using System; 
using System.IO; 
using System.Runtime.Serialization.Json; 
using System.Text; 

namespace TestSerialization 
{ 
    #region Program 
    /// <summary> 
    /// Class Program - this is the entry point. 
    /// </summary> 
    class Program 
    { 
     #region Main 
     /// <summary> 
     /// Defines the entry point of the application. 
     /// </summary> 
     /// <param name="args">The arguments.</param> 
     static void Main(string[] args) 
     { 
      TestThis(); 
      Console.ReadLine(); 
     } 
     #endregion 

     #region TestThis 
     /// <summary> 
     /// Tests the various scenarios 
     /// </summary> 
     private static void TestThis() 
     { 
      try 
      { 
       // 
       // Build the test objects 
       // 
       ClassWithNoConstructor classWithNoConstructor = new ClassWithNoConstructor { Int01 = 1, Int02 = 2, String01 = "hello01", String02 = "world02", OtherClass01 = new EmbeddedClass { OC01 = "OCString01", OC02 = "OCString02" } }; 
       ClassWithConstructorForStrings classWithConstructorForStrings = new ClassWithConstructorForStrings("hello03", "world04") { Int01 = 3, Int02 = 4, OtherClass01 = new EmbeddedClass { OC01 = "OCString03", OC02 = "OCString04" } }; 
       ClassWithEmptyConstructor classWithEmptyConstructor = new ClassWithEmptyConstructor(); 
       classWithEmptyConstructor.Int01 = 5; 
       classWithEmptyConstructor.Int02 = 6; 
       classWithEmptyConstructor.String01 = "hello05"; 
       classWithEmptyConstructor.String02 = "world06"; 
       classWithEmptyConstructor.OtherClass01 = new EmbeddedClass(); 
       classWithEmptyConstructor.OtherClass01.OC01 = "OCString05"; 
       classWithEmptyConstructor.OtherClass01.OC02 = "OCString06"; 
       try 
       { 
        string json = JsonHelper.Serialize(classWithNoConstructor, false); 
        Console.WriteLine(">>> {0} <<<",classWithNoConstructor.GetType().Name); 
        Console.WriteLine("NewtonSoft : {0}", json); 
        json = JsonHelper.Serialize(classWithNoConstructor, true); 
        Console.WriteLine("DataContract: {0}", json); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine(ex); 
       } 
       try 
       { 
        string json = JsonHelper.Serialize(classWithConstructorForStrings, false); 
        Console.WriteLine(">>> {0} <<<", classWithConstructorForStrings.GetType().Name); 
        Console.WriteLine("NewtonSoft : {0}", json); 
        json = JsonHelper.Serialize(classWithConstructorForStrings, true); 
        Console.WriteLine("DataContract: {0}", json); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine(ex); 
       } 
       try 
       { 
        string json = JsonHelper.Serialize(classWithEmptyConstructor, false); 
        Console.WriteLine(">>> {0} <<<", classWithEmptyConstructor.GetType().Name); 
        Console.WriteLine("NewtonSoft : {0}", json); 
        json = JsonHelper.Serialize(classWithEmptyConstructor, true); 
        Console.WriteLine("DataContract: {0}", json); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine(ex); 
       } 
       Console.WriteLine(); 
       ShowComparison<ClassWithNoConstructor>(classWithNoConstructor); 
       ShowComparison<ClassWithConstructorForStrings>(classWithConstructorForStrings); 
       ShowComparison<ClassWithEmptyConstructor>(classWithEmptyConstructor); 

      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex); 
      } 
     } 
     #endregion 

     #region ShowComparison 
     /// <summary> 
     /// Shows the comparison between Newtonsoft and the Data Contract serializer. 
     /// </summary> 
     /// <typeparam name="T">Type of the data you are comparing</typeparam> 
     /// <param name="data">The data object you wish to compare.</param> 
     private static void ShowComparison<T>(object data) 
     { 
      // 
      // Show them as strings, deserialize them and show if they deserialized correctly 
      // 
      StringBuilder sb = new StringBuilder(); 
      bool isTheSameNS = false; 
      bool isTheSameDC = false; 
      Type typeOfTheData = data.GetType(); 

      bool DataContractFlag = false; 
      string jsonNS = JsonHelper.Serialize(data, DataContractFlag); 
      T deserializedNS = JsonHelper.DeserializeObject<T>(jsonNS, DataContractFlag); 

      DataContractFlag = true; 
      string jsonDC = JsonHelper.Serialize(data, DataContractFlag); 
      T deserializedDC = JsonHelper.DeserializeObject<T>(jsonDC, DataContractFlag); 

      if (typeOfTheData == typeof(ClassWithNoConstructor)) 
      { 
       isTheSameNS = ((ClassWithNoConstructor)data).IsEqualTo(deserializedNS as ClassWithNoConstructor); 
       isTheSameDC = ((ClassWithNoConstructor)data).IsEqualTo(deserializedDC as ClassWithNoConstructor); 
      } 
      else if (typeOfTheData == typeof(ClassWithConstructorForStrings)) 
      { 
       isTheSameNS = ((ClassWithConstructorForStrings)data).IsEqualTo(deserializedNS as ClassWithConstructorForStrings); 
       isTheSameDC = ((ClassWithConstructorForStrings)data).IsEqualTo(deserializedDC as ClassWithConstructorForStrings); 
      } 
      else if (typeOfTheData == typeof(ClassWithEmptyConstructor)) 
      { 
       isTheSameNS = ((ClassWithEmptyConstructor)data).IsEqualTo(deserializedNS as ClassWithEmptyConstructor); 
       isTheSameDC = ((ClassWithEmptyConstructor)data).IsEqualTo(deserializedDC as ClassWithEmptyConstructor); 
      } 

      sb.AppendLine(string.Format("======== {0} ======================================================", typeOfTheData.Name)); 
      sb.AppendLine(string.Format("++++ NewtonSoft +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")); 
      sb.AppendLine(string.Format("Json: {0}", jsonNS)); 
      sb.AppendLine(string.Format("Does Serialized object match original? {0}", isTheSameNS)); 
      sb.AppendLine("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); 

      sb.AppendLine(string.Format("++++ DataContract +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")); 
      sb.AppendLine(string.Format("Json: {0}", jsonDC)); 
      sb.AppendLine(string.Format("Does Serialized object match original? {0}", isTheSameDC)); 
      sb.AppendLine("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); 
      sb.AppendLine(string.Format("Does DataContract Json Match Newtownsoft Json? {0}", jsonNS.Equals(jsonDC))); 
      sb.AppendLine("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); 
      Console.WriteLine(sb.ToString()); 
      sb.Clear(); 
     } 

     #endregion 
    } 
    #endregion 

    #region JsonHelper 
    /// <summary> 
    /// Class JsonHelper. Wraps different ways to convert models to and from Json 
    /// </summary> 
    public static class JsonHelper 
    { 
     #region Serialize 
     /// <summary> 
     /// Serializes the specified model. 
     /// </summary> 
     /// <param name="model">The model that you wish to serialize.</param> 
     /// <param name="useDataContract">if set to <c>true</c> use the DataContractSerializer.</param> 
     /// <returns>System.String.</returns> 
     public static string Serialize(object model, bool useDataContract = false) 
     { 
      if (useDataContract) 
      { 
       string result = string.Empty; 
       DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings { SerializeReadOnlyTypes = true }; 
       DataContractJsonSerializer js = new DataContractJsonSerializer(model.GetType(), settings); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        js.WriteObject(ms, model); 
        ms.Position = 0; 
        using (StreamReader sr = new StreamReader(ms)) 
        { 
         result = sr.ReadToEnd(); 
        } 
       } 
       return result; 
      } 
      else 
      { 
       return Newtonsoft.Json.JsonConvert.SerializeObject(model); 
      } 
     } 
     #endregion 

     #region DeserializeObject 
     /// <summary> 
     /// Deserializes the object. 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="json">The json string you wish to deserialize.</param> 
     /// <param name="useDataContract">if set to <c>true</c> use the DataContractSerializer.</param> 
     /// <returns>T.</returns> 
     public static T DeserializeObject<T>(string json, bool useDataContract = false) 
     { 
      if (useDataContract) 
      { 
       DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(T)); 
       using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json))) 
       { 
        T result = (T)js.ReadObject(ms); 
        return result; 
       } 
      } 
      else 
      { 
       return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json); 
      } 
     } 
     #endregion 
    } 
    #endregion 

    #region ClassWithEmptyConstructor 
    /// <summary> 
    /// Class ClassWithEmptyConstructor - Just another test case to be sure a "default empty" contstructor still works. 
    /// </summary> 
    public class ClassWithEmptyConstructor 
    { 
     public ClassWithEmptyConstructor() { } 
     public int Int01 { get; set; } 
     public int Int02 { get; set; } 
     public string String01 { get; set; } 
     public string String02 { get; set; } 
     public string ReadOnly { get { return "ReadOnly03"; } } 

     public EmbeddedClass OtherClass01 { get; set; } 

     public bool IsEqualTo(ClassWithEmptyConstructor other) 
     { 
      if ((other.Int01 == this.Int01) 
       && (other.Int02 == this.Int02) 
       && (other.String01 == this.String01) 
       && (other.String02 == this.String02) 
       && (other.OtherClass01.Equals(this.OtherClass01))) 
       return true; 
      else 
       return false; 
     } 
    } 
    #endregion 

    #region ClassWithNoConstructor 
    /// <summary> 
    /// Class ClassWithNoConstructor - just a plain class to be initialized by the calling program. 
    /// </summary> 
    public class ClassWithNoConstructor 
    { 
     public int Int01 { get; set; } 
     public int Int02 { get; set; } 
     public string String01 { get; set; } 
     public string String02 { get; set; } 
     public string ReadOnly { get { return "ReadOnly01"; } } 
     public EmbeddedClass OtherClass01 { get; set; } 

     public bool IsEqualTo(ClassWithNoConstructor other) 
     { 
      if ((other.Int01 == this.Int01) 
       && (other.Int02 == this.Int02) 
       && (other.String01 == this.String01) 
       && (other.String02 == this.String02) 
       && (other.OtherClass01.Equals(this.OtherClass01))) 
       return true; 
      else 
       return false; 
     } 
    } 
    #endregion 

    #region ClassWithConstructorForStrings 
    /// <summary> 
    /// Class ClassWithConstructorForStrings - a data class with a constructor that takes two strings 
    /// and also an empty constructor because the DataContract serializer requires it. The Newtonsoft 
    /// serializer does NOT require the empty constructor 
    /// </summary> 
    public class ClassWithConstructorForStrings 
    { 
     public ClassWithConstructorForStrings() { } 
     public ClassWithConstructorForStrings(string s01, string s02) { String01 = s01; String02 = s02; } 
     public int Int01 { get; set; } 
     public int Int02 { get; set; } 
     public string String01 { get; set; } 
     public string String02 { get; set; } 
     public string ReadOnly { get { return "ReadOnly02"; } } 
     public EmbeddedClass OtherClass01 { get; set; } 

     public bool IsEqualTo(ClassWithConstructorForStrings other) 
     { 
      if ((other.Int01 == this.Int01) 
       && (other.Int02 == this.Int02) 
       && (other.String01 == this.String01) 
       && (other.String02 == this.String02) 
       && (other.OtherClass01.Equals(this.OtherClass01))) 
       return true; 
      else 
       return false; 
     } 
    } 
    #endregion 

    #region EmbeddedClass 
    /// <summary> 
    /// Class EmbeddedClass - used to test a complex class serialization 
    /// This fails in NewtonSoft/Xamarin/iOS because it calls a CodeEmitter which apparently iOS does not allow. 
    /// </summary> 
    public class EmbeddedClass 
    { 

     public string OC01 { get; set; } 
     public string OC02 { get; set; } 

     public override bool Equals(object obj) 
     { 
      EmbeddedClass other = (EmbeddedClass)obj; 
      if (other.OC01 == OC01 && other.OC02 == OC02) 
       return true; 
      else 
       return false; 
     } 
    } 
    #endregion 

} 
+0

'DataContractJsonSerializer' erbt von [' XmlObjectSerializer'] (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.xmlobjectserializer.aspx) unter der Haube, und verwendet ein [spezialisierter XML-Writer] (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.jsonreaderwrwrfacturing_methods.aspx) um JSON zu schreiben. Die Ausnahme, die Sie sehen, ist also plausibel. Können Sie die vollständige 'ToString()' -Ausgabe der Ausnahme teilen, einschließlich des Ausnahmetyps, der Nachricht und des Tracebacks? – dbc

+0

hmmm im schlimmsten Fall wirst du Code wie folgt haben: 'if (platform.ios) {benutze .Net Serializer} else {nutze NewtonSoft}', ich hoffe jemand gibt dir Besseres als das :) – niceman

+0

Ich gehe hin Ich schlage vor, Sie versuchen folgendes: 1) Ordnen Sie Ihren Serializer zu, indem Sie 'new DataContractJsonSerializer (model.GetType())' - dh verwenden Sie nicht 'DataContractJsonSerializerSettings'. Löst das das Problem? 2) Weisen Sie die Einstellungen zu, aber tun Sie 'var settings = new DataContractJsonSerializerSettings {SerializeReadOnlyTypes = true, RootName =" root "};'. Führt das Festlegen des ['RootName'] (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.dataccontractjsonserializersettings.rootname.aspx) das Problem explizit aus? – dbc

Antwort

0

Nun, auf der Grundlage der oben genannten Vorschläge, habe ich versucht, die folgenden in meinem Json Helfer:

#region Serialize 
     /// <summary> 
     /// Serializes the specified model. 
     /// </summary> 
     /// <param name="model">The model that you wish to serialize.</param> 
     /// <param name="useDataContract">if set to <c>true</c> use the DataContractSerializer.</param> 
     /// <returns>System.String.</returns> 
     public static string Serialize(object model, bool useDataContract = false) 
     { 
      if (useDataContract) 
      { 
       string result = string.Empty; 
       DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings { SerializeReadOnlyTypes = true, RootName = "root", MaxItemsInObjectGraph = 1000 }; 
       DataContractJsonSerializer js = new DataContractJsonSerializer(model.GetType(), settings); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        js.WriteObject(ms, model); 
        ms.Position = 0; 
        using (StreamReader sr = new StreamReader(ms)) 
        { 
         result = sr.ReadToEnd(); 
        } 
       } 
       return result; 
      } 
      else 
      { 
       return Newtonsoft.Json.JsonConvert.SerializeObject(model); 
      } 
     } 
     #endregion 

, dass das Problem behoben zu haben scheint. Für die Neugierigen sind die zwei Stack-Traces des PI, die früher gefragt wurden (zusammen mit der endgültigen Version, die tatsächlich funktioniert hat) angehängt. Danke, allerseits!

=========== Stack Trace #1 ===================== 

Code: 
DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings { SerializeReadOnlyTypes = true }; 
DataContractJsonSerializer js = new DataContractJsonSerializer(model.GetType(), settings); 


System.ArgumentNullException: Argument cannot be null. 
Parameter name: rootName 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer..ctor (System.Type type, System.String rootName, IEnumerable`1 knownTypes, Int32 maxItemsInObjectGraph, Boolean ignoreExtensionDataObject, Boolean alwaysEmitTypeInformation) [0x00000] in <filename unknown>:0 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer..ctor (System.Type type, System.String rootName, IEnumerable`1 knownTypes, Int32 maxItemsInObjectGraph, Boolean ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, Boolean alwaysEmitTypeInformation) [0x00000] in <filename unknown>:0 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer..ctor (System.Type type, System.Runtime.Serialization.Json.DataContractJsonSerializerSettings settings) [0x00000] in <filename unknown>:0 
    at TestSerialization.JsonHelper.Serialize (System.Object model, Boolean useDataContract) [0x00000] in <filename unknown>:0 
    at TestSerialization.Program.TestThis() [0x00000] in <filename unknown>:0 

=========== Stack Trace #2 ===================== 

Code: 
DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings { SerializeReadOnlyTypes = true, RootName="root" }; 
DataContractJsonSerializer js = new DataContractJsonSerializer(model.GetType(), settings); 


System.Runtime.Serialization.SerializationException: There was an error during serialization for object of type TestSerialization.ClassWithNoConstructor ---> System.Runtime.Serialization.SerializationException: The object graph exceeded the maximum object count '0' specified in the serializer 
    at System.Runtime.Serialization.Json.JsonSerializationWriter.WriteObjectContent (System.Object graph, Boolean top, Boolean outputTypeName) [0x00000] in <filename unknown>:0 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer.WriteObjectContent (System.Xml.XmlWriter writer, System.Object graph) [0x00000] in <filename unknown>:0 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer.WriteObject (System.Xml.XmlWriter writer, System.Object graph) [0x00000] in <filename unknown>:0 
    --- End of inner exception stack trace --- 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer.WriteObject (System.Xml.XmlWriter writer, System.Object graph) [0x00000] in <filename unknown>:0 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer.WriteObject (System.Xml.XmlDictionaryWriter writer, System.Object graph) [0x00000] in <filename unknown>:0 
    at System.Runtime.Serialization.Json.DataContractJsonSerializer.WriteObject (System.IO.Stream stream, System.Object graph) [0x00000] in <filename unknown>:0 
    at TestSerialization.JsonHelper.Serialize (System.Object model, Boolean useDataContract) [0x00000] in <filename unknown>:0 
    at TestSerialization.Program.TestThis() [0x00000] in <filename unknown>:0 

=========== Stack Trace #3 ===================== 

Code: 
DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings { SerializeReadOnlyTypes = true, RootName = "root", MaxItemsInObjectGraph = 1000 }; 
DataContractJsonSerializer js = new DataContractJsonSerializer(model.GetType(), settings); 

>>> ClassWithNoConstructor <<< 
NewtonSoft : {"Int01":1,"Int02":2,"String01":"hello01","String02":"world02","ReadOnly":"ReadOnly01","OtherClass01":{"OC01":"OCString01","OC02":"OCString02"}} 
DataContract: {"Int01":1,"Int02":2,"OtherClass01":{"OC01":"OCString01","OC02":"OCString02"},"String01":"hello01","String02":"world02"} 
>>> ClassWithConstructorForStrings <<< 
NewtonSoft : {"Int01":3,"Int02":4,"String01":"hello03","String02":"world04","ReadOnly":"ReadOnly02","OtherClass01":{"OC01":"OCString03","OC02":"OCString04"}} 
DataContract: {"Int01":3,"Int02":4,"OtherClass01":{"OC01":"OCString03","OC02":"OCString04"},"String01":"hello03","String02":"world04"} 
>>> ClassWithEmptyConstructor <<< 
NewtonSoft : {"Int01":5,"Int02":6,"String01":"hello05","String02":"world06","ReadOnly":"ReadOnly03","OtherClass01":{"OC01":"OCString05","OC02":"OCString06"}} 
DataContract: {"Int01":5,"Int02":6,"OtherClass01":{"OC01":"OCString05","OC02":"OCString06"},"String01":"hello05","String02":"world06"} 

======== ClassWithNoConstructor ====================================================== 
++++ NewtonSoft +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Json: {"Int01":1,"Int02":2,"String01":"hello01","String02":"world02","ReadOnly":"ReadOnly01","OtherClass01":{"OC01":"OCString01","OC02":"OCString02"}} 
Does Serialized object match original? True 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++ DataContract +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Json: {"Int01":1,"Int02":2,"OtherClass01":{"OC01":"OCString01","OC02":"OCString02"},"String01":"hello01","String02":"world02"} 
Does Serialized object match original? True 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Does DataContract Json Match Newtownsoft Json? False 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

======== ClassWithConstructorForStrings ====================================================== 
++++ NewtonSoft +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Json: {"Int01":3,"Int02":4,"String01":"hello03","String02":"world04","ReadOnly":"ReadOnly02","OtherClass01":{"OC01":"OCString03","OC02":"OCString04"}} 
Does Serialized object match original? True 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++ DataContract +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Json: {"Int01":3,"Int02":4,"OtherClass01":{"OC01":"OCString03","OC02":"OCString04"},"String01":"hello03","String02":"world04"} 
Does Serialized object match original? True 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Does DataContract Json Match Newtownsoft Json? False 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 

======== ClassWithEmptyConstructor ====================================================== 
++++ NewtonSoft +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Json: {"Int01":5,"Int02":6,"String01":"hello05","String02":"world06","ReadOnly":"ReadOnly03","OtherClass01":{"OC01":"OCString05","OC02":"OCString06"}} 
Does Serialized object match original? True 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
++++ DataContract +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Json: {"Int01":5,"Int02":6,"OtherClass01":{"OC01":"OCString05","OC02":"OCString06"},"String01":"hello05","String02":"world06"} 
Does Serialized object match original? True 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Does DataContract Json Match Newtownsoft Json? False 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++