1

I need to implement a custom functionality a bit similar Dictionary but with the possibility to insert duplicate keys. So basically what I need from Dictionary is the possibility to serialize the object as the following JSON:

{
  "One":"Value 1",
  "Two":"Value x",
  "One":"Value 10",
  "Two":"Value 100"
} 

As you can see above I have duplicate keys ...

Any advice? The whole point is the JSON output in the format above

Edit:

KeyValuePair<string,string> doesn't work!

This is the outcome:

[{"Key":"One","Value":"Two"},{"Key":"One","Value":"Two"}]

As you can see serialized as JSON will brink the Key and Value keywords in place where a Dictionary will replace the Key with the actual key-value and the value with the value provided.

user2818430
  • 5,853
  • 21
  • 82
  • 148

4 Answers4

8

You can use a List<KeyValuePair<TKey, TValue>> instead of a Dictionary<TKey, TValue>. In your case, it would be a List<KeyValuePair<string, string>>.

Edit:

If you're using Json.NET for serialization of the JSON, you can achieve your desired output using a custom converter. The answer here provides it (I made slight modifications):

class KeyValuePairConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, 
                                                      JsonSerializer serializer)
    {
        var list = value as List<KeyValuePair<string, string>>;
        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, string>>);
    }
}
Community
  • 1
  • 1
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • KeyValuePair will output Key and Value within the JSON but Dictionary will provide the actual values as Key and value ... I made an edit to my question. – user2818430 May 20 '15 at 15:23
  • @YuvalItzchakov please see related post: http://stackoverflow.com/questions/39583463/converting-json-object-to-data-entities-models-mymodel – Euridice01 Sep 20 '16 at 01:17
2

You may want to use List<Tuple<string,string>>

 List<Tuple<string, string>> values = new List<Tuple<string, string>>();
 values.Add(new Tuple<string, string>("One", "Value 1"));
 values.Add(new Tuple<string, string>("Two", "Value x"));
 values.Add(new Tuple<string, string>("One", "Value 10"));

EDIT: If the property names are important, why not simply try something like: List<MyClass>

class MyClass
{
    public string Key { get; set; }

    public string Value { get; set; }
}
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
  • Tuple doesn't work either, because will output Item1, Item2, etc etc. please check the JSON example I provided in the question. – user2818430 May 20 '15 at 15:25
0

Use an array of a custom class.

MyClass[] array;

public class MyClass
{
    public string Key { get; set; }
    public string Value { get; set; }
}
0

You could do something like this (knocked it up quickly in console) but shoudl be enough to get the idea...

using System.IO;
using System;
using System.Text;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
         List<Tuple<string, string>> values = new List<Tuple<string, string>>();
         values.Add(new Tuple<string, string>("One", "Value 1"));
         values.Add(new Tuple<string, string>("Two", "Value x"));
         values.Add(new Tuple<string, string>("One", "Value 10"));
         Console.Write(Format.ToJson(values));
    }
}

static class Format {
    public static string ToJson(List<Tuple<string, string>> values) {
        StringBuilder builder = new StringBuilder();
        foreach(var item in values) {
            builder.Append(string.Format("{{{0}:{1}}},", item.Item1, item.Item2));
        }
        return "{" + builder.ToString() + "}";
    }
}
Luke Baughan
  • 4,658
  • 3
  • 31
  • 54