Another way to accomplish this is to use a custom ContractResolver
. That way you do not have to subclass Dictionary<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:
class DictionaryAsArrayResolver : DefaultContractResolver
{
protected override JsonContract CreateContract(Type objectType)
{
if (objectType.GetInterfaces().Any(i => i == typeof(IDictionary) ||
(i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>))))
{
return base.CreateArrayContract(objectType);
}
return base.CreateContract(objectType);
}
}
To use the resolver, add it to your JsonSerializerSettings
, then pass the settings to JsonConvert.SerializeObject()
like this:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new DictionaryAsArrayResolver();
string json = JsonConvert.SerializeObject(obj, settings);
Here is a working demo.