Search code examples
c#jsonserialization

JSON Serialize List<KeyValuePair<string, object>>


I used a Dictionary in a Web API project, which is serializing like that in JSON:

{"keyname":{objectvalue},"keyname2:"....

Since I have duplicate keys I could't use Dictionary type any more, and instead now I'm using List<KeyValuePair<string,object>>.

But this is serializing that way:

[{"Key":"keyname","Value":"objectvalue"}...

Is there a way to have the List<KeyValuePair> serialize the same way a dictionary does?

Thanks.


Solution

  • If you use the Newtonsoft Json.NET library you can do the following.

    Define a converter to write the list of key/value pairs the way you want:

    class MyConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            List<KeyValuePair<string, object>> list = value as List<KeyValuePair<string, object>>;
            writer.WriteStartArray();
            foreach (var item in list)
            {
                writer.WriteStartObject();
                writer.WritePropertyName(item.Key);
                writer.WriteValue(item.Value);
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            // TODO...
        }
    
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(List<KeyValuePair<string, object>>);
        }
    }
    

    Then use the converter:

    var keyValuePairs = new List<KeyValuePair<string, object>>
                        {
                            new KeyValuePair<string, object>("one", 1),
                            new KeyValuePair<string, object>("two", 2),
                            new KeyValuePair<string, object>("three", 3)
                        };
    
    JsonSerializerSettings settings = new JsonSerializerSettings { Converters = new [] {new MyConverter()} };
    string json = JsonConvert.SerializeObject(keyValuePairs, settings);
    

    This generates [{"one":1},{"two":2},{"three":3}]