To solve this, I created a dictionary object that accepted duplicate keys (copied from Duplicate keys in .NET dictionaries?), and added a JsonConverter to control how the object was serialized;
  public class MultiMap<TKey, TValue>
  {
    private readonly Dictionary<TKey, IList<TValue>> storage;
    public MultiMap()
    {
      storage = new Dictionary<TKey, IList<TValue>>();
    }
    public void Add(TKey key, TValue value)
    {
      if (!storage.ContainsKey(key)) storage.Add(key, new List<TValue>());
      storage[key].Add(value);
    }
    public IEnumerable<TKey> Keys
    {
      get { return storage.Keys; }
    }
    public bool ContainsKey(TKey key)
    {
      return storage.ContainsKey(key);
    }
    public IList<TValue> this[TKey key]
    {
      get
      {
        if (!storage.ContainsKey(key))
          throw new KeyNotFoundException(
              string.Format(
                  "The given key {0} was not found in the collection.", key));
        return storage[key];
      }
    }
  }
The JsonConverter object was as follows (I didn't bother with the read as I didn't need it, but it could be easily implemented);
public class MultiMapJsonConverter<TKey, TValue> : JsonConverter
  {
    public override bool CanConvert(Type objectType)
    {
      return objectType == typeof(MultiMap<TKey, TValue>);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
      throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }
    public override bool CanRead
    {
      get { return false; }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
      writer.WriteStartObject();
      MultiMap<TKey, TValue> m = (MultiMap<TKey, TValue>)value;
      foreach (TKey key in m.Keys)
      {
        foreach (TValue val in m[key])
        {
          writer.WritePropertyName(key.ToString());
          JToken.FromObject(val).WriteTo(writer);
        }
      }
      writer.WriteEndObject();
    }
  }
With this defined , the following code;
var mm = new MultiMap<string, object>();
mm.Add("color", "dd3333");
mm.Add("linewidth", 2);
mm.Add("dataset", new int[] { 3,4,5,6 });
mm.Add("dataset", new int[] { 5,6,7,8 });
var json = JsonConvert.SerializeObject(mm, new JsonConverter[] { new MultiMapJsonConverter<string, object>() });
gives me the json output;
{"color":"dd3333","linewidth":2,"dataset":[3,4,5,6],"dataset":[5,6,7,8]}