mgholam / fastJSON

Smallest, fastest polymorphic JSON serializer
https://www.codeproject.com/Articles/159450/fastJSON-Smallest-Fastest-Polymorphic-JSON-Seriali
MIT License
479 stars 147 forks source link

Strange Serialization result #143

Closed frankinstien111 closed 10 months ago

frankinstien111 commented 10 months ago

I put a class into a List within another class. Below are images of the objects before they are serialized:

ArrayItem1 ArrayItem2 ArrayItem3 ArrayItem4

This is what it serializes into:

{"$type":"6","DimensionMatrix":[{"$type":"7","Dimension":1,"Label":"High Arousal","Mid":2.5,"Status":true,"Maxium":5,"Minimum":0},{"$i":21},{"$i":21},{"$i":21}],"Title":"ArousalValence","Errors":[],"HowToCompare":"isWithinRange","OperatorType":"maxPoint","Status":true}

For some reason, it appears to optimize the array by serializing the first item in the array and then grouping all the others as {"$i":21},{"$i":21},{"$i":21}. When it deserializes all the class labels are "High Arousal" which is incorrect. Below is the class object definition:

` [Serializable] public class MaxMidMin { [DataMember] public int Dimension { set; get; } [DataMember] public String Label { set; get; } private double _max { set; get; } private double _min { set; get; } public double Mid { set; get; } [DataMember] private bool maxWasSet; [DataMember] private bool minWasSet; public bool Status { set; get; } GenericIndexKey rangeKey;

  public MaxMidMin()
  {
      Dimension = 1;            
  }

  public MaxMidMin(int dim)
  {
      if (dim > 0)
          Dimension = dim;
      else
          throw new Exception("A dimension cannot be less than 1");
  }

  public MaxMidMin(string label, int dim = 1)
      :this(dim)
  {
      Label = label;
  }     

  [DataMember]
  public double Maxium
  {
      set
      {
          _max = value;
          maxWasSet = true;
          InitializeMidPoint();
      }
      get
      {
          return _max;
      }
  }

  [DataMember]
  public double Minimum
  {
      set
      {
          _min = value;
          minWasSet = true;
          InitializeMidPoint();
      }
      get
      {
          return _min;
      }
  }    

} `

frankinstien111 commented 10 months ago

Could you point me to where the code that makes that decision to consolidate the array objects is located? I'm under a time constraint to find a solution for this.

Thx

mgholam commented 10 months ago

$type and $i means you have circular references. All your $i are 21 in your sample. debug private void WriteObject(object obj)

frankinstien111 commented 10 months ago

The problem was the nested classes would return zero if its object key was null where it would not generate the correct hashcode. Also, the approach of inserting an uninitialized class object into a dictionary the serializer would throw an exception where returning zero from the hash function prevented the error. In any case, code was implemented to do both, return zero when not initialized, and when the object key is null initialize an object key.