Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Newtonsoft.Json serializing some items twice

Tags:

json.net

f#

I noticed some strange output from Newtonsoft.Json today, I'm not sure if it is an interaction with F# types or something that can occur in C# as well, so I've tagged both. I have a list of the following record being serialized:

 type SplitTracker = 
  {  
     [<JsonIgnore>]   
     split            : SplitDefinition
     mutable start    : duration
     mutable ``end``  : duration
     mutable lapCount : int
     mutable duration : duration Option
  }   

I serialize it with JsonConvert.SerializeObject and I get the following odd output:

 "splits": [
  {
    "start@": "0.00",
    "end@": "0.00",
    "lapCount@": 0,
    "duration@": null,
    "start": "0.00",
    "end": "0.00",
    "lapCount": 0,
    "duration": null
  },
  {
    "start@": "0.00",
    "end@": "0.00",
    "lapCount@": 0,
    "duration@": null,
    "start": "0.00",
    "end": "0.00",
    "lapCount": 0,
    "duration": null
  }

Anyone know why that might be happening? The data is correct, the duplication of fields with the "@" symbol is the issue.

like image 455
jackmott Avatar asked Mar 30 '16 13:03

jackmott


People also ask

Does JSON net serialize private fields?

Private and protected members are not serialized.

What is Stringenumconverter?

Converts an Enum to and from its name string value. Newtonsoft.Json. JsonConverter. Newtonsoft.Json.Converters.

What is JsonExtensionData?

[JsonExtensionData] allows you to do is to serialize elements of a JSON document which does not have matching properties on the destination object to the dictionary which is decorated with the [JsonExtensionData] attribute.

What is JsonObjectAttribute?

JsonObjectAttribute(String) Initializes a new instance of the JsonObjectAttribute class with the specified container Id. JsonObjectAttribute(MemberSerialization) Initializes a new instance of the JsonObjectAttribute class with the specified member serialization.


1 Answers

The way you have defined your record is the culprit here. Record fields are exposed as properties - but you are using mutable properties. F# will turn that into a class that has fields for each of your mutables (the name is the property name, prefixed with @), and properties that read out those.

Json will now attempt to serialize all fields and all properties - hence you get the duplication.

Try it out in F# interactive:

type SplitTracker = 
    {  
        mutable start    : float
    }   
let t = typeof<SplitTracker>
let fields1 = t.GetFields() // This will give you a field '@start'
let props1 = t.GetProperties() // This will give you a property 'start'

Contrast that with what you get when using a plain record:

type SplitTracker2 = 
    {  
        start    : float
    }   
let t2 = typeof<SplitTracker2>
let fields2 = t2.GetFields() // You will not see any fields
let props2 = t2.GetProperties() // There is a single property 'start'

This should serialize correctly. Apart from that, it makes your code more idiomatic.

like image 166
Anton Schwaighofer Avatar answered Nov 02 '22 15:11

Anton Schwaighofer