Json.Net typically serializes a Dictionary<k,v>
into a collection;
"MyDict": {
"Apples": {
"Taste": 1341181398,
"Title": "Granny Smith",
},
"Oranges": {
"Taste": 9999999999,
"Title": "Coxes Pippin",
},
}
Which is great. And from looking around on SO it seems to be what most people want. However, in this particular case, I want to serialize between my Dictionary<k,v>
and the Array format instead;
"MyDict": [
"k": "Apples",
"v": {
"Taste": 1341181398,
"Title": "Granny Smith",
}
},
"k:": "Oranges",
"v:": {
"Taste": 9999999999,
"Title": "Coxes Pippin",
}
},
]
Is there an easy way to do this with my existing field type? Is there an attribute I can annotate for instance?
Ah, it turns out this is as straightforward as I'd hoped. My
Dictionary<k,v>
is subclassed already and I found that I can annotate it with[JsonArrayAttribute]
. That gives me exactly the format I need;gregmac's answer was helpful, but didn't quite work. The following is the same idea... without the puns.
or of course
Then to json
I'm not exactly sure why, but the custom ContractResolver by Brian Rogers listed above didn't work for me. It seemed to get into an endless loop somewhere internally. Possibly due to other parts of my json.net setup.
Anyway - this workaround did the trick for me.
For this example, I'll use the dictonary:
which serializes (with
Newtonsoft.Json.JsonConvert.SerializeObject(myDict)
) to:You could do a transform using LINQ to create an anonymous object, and serialize that:
Or you could use a real object
and either the above or the alternative LINQ syntax:
Either way, this serializes to:
.NET Fiddle link: https://dotnetfiddle.net/LhisVW
Another way to accomplish this is to use a custom
ContractResolver
. That way you do not have to subclassDictionary<K,V>
nor apply a transform each time you serialize, as suggested in other answers.The following resolver will cause ALL dictionaries to be serialized as an array of objects with "Key" and "Value" properties:
To use the resolver, add it to your
JsonSerializerSettings
, then pass the settings toJsonConvert.SerializeObject()
like this:Here is a working demo.
The simplest solution I found is to convert your
Dictionary<string, string>
to aList<KeyValuePair<string, string>>
. JSON.NET then converts yourList
into an array of objects with the form{ Key: 'keyname', Value: 'value' }
. This works well if you accept the required model change and don't want to subclass yourDictionary
.