Сериализовать словарь как массив (пар ключей)

Json.Net обычно сериализует Dictionary в коллекцию;

 "MyDict": { "Apples": { "Taste": 1341181398, "Title": "Granny Smith", }, "Oranges": { "Taste": 9999999999, "Title": "Coxes Pippin", }, } 

Это здорово. И, глядя на SO, похоже, это то, чего хотят большинство людей. Однако в этом конкретном случае я хочу сериализовать между моим Dictionary и форматом Array;

 "MyDict": [ "k": "Apples", "v": { "Taste": 1341181398, "Title": "Granny Smith", } }, "k:": "Oranges", "v:": { "Taste": 9999999999, "Title": "Coxes Pippin", } }, ] 

Есть ли простой способ сделать это с помощью моего существующего типа поля? Есть ли атрибут, который я могу аннотировать, например?

Другой способ добиться этого – использовать пользовательский ContractResolver . Таким образом, вам не нужно подclassифицировать Dictionary и применять преобразование при каждом сериализации, как это предлагается в других ответах.

Следующий резольвер приведет к сериализации ALL словарей как массива объектов с свойствами «Key» и «Value»:

 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); } } 

Чтобы использовать резольвер, добавьте его в свои JsonSerializerSettings , а затем передайте настройки JsonConvert.SerializeObject() следующим образом:

 JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new DictionaryAsArrayResolver(); string json = JsonConvert.SerializeObject(obj, settings); 

Вот рабочая демонстрация .

О, оказывается, это так же просто, как я надеялся. Мой Dictionary уже подclassифицирован, и я обнаружил, что могу его аннотировать с помощью [JsonArrayAttribute] . Это дает мне именно тот формат, который мне нужен;

 "MyDict": [ { "Key": "Apples", "Value": { "Taste": 1341181398, "Title": "Granny Smith", } }, { "Key:": "Oranges", "Value:": { "Taste": 9999999999, "Title": "Coxes Pippin", } }, ] 

В этом примере я воспользуюсь изречением:

 var myDict = new Dictionary() { {"a","123"}, {"b","234"}, {"c","345"} }; 

который сериализует (с Newtonsoft.Json.JsonConvert.SerializeObject(myDict) ):

 {"a":"123","b":"234","c":"345"} 

Вы можете сделать преобразование с помощью LINQ для создания анонимного объекта и сериализовать это:

  var myDictTransformed = from key in myDict.Keys select new { k = key, v = myDict[key] }; 

Или вы можете использовать реальный объект

 class MyDictEntry { public string k { get; set; } public string v { get; set; } } 

и либо выше, либо альтернативный синтаксис LINQ:

 var myDictTransformed = myDict.Keys.AsEnumerable() .Select(key => new MyDictEntry{ k = key, v = myDict[key] }); 

В любом случае, это сериализуется для:

 [ {"k":"a", "v":"123"}, {"k":"b", "v":"234"}, {"k":"c", "v":"345"} ] 

Ссылка .NET Fiddle: https://dotnetfiddle.net/LhisVW

Самое простое решение, которое я нашел, – это преобразовать Dictionary в List> . Затем JSON.NET преобразует ваш List в массив объектов с формой { Key: 'keyname', Value: 'value' } . Это хорошо работает, если вы принимаете требуемое изменение модели и не хотите подclassифицировать Dictionary .

Ответ gregmac был полезен, но не совсем сработал. Следующее – та же идея … без каламбуров.

 var dictionaryTransformed = dictionary.Select(item => item.Key).Select(i => new {Key = i, Value = dictionary[i] }); 

или, конечно же,

 var dictionaryTransformed = dictionary.Select(item => new {item.Key, Value = dictionary[item.Key] }); 

Затем к json

 var json = (new JavaScriptSerializer()).Serialize( new { Container = dictionaryTransformed.ToArray() } ) 
  • Создайте строго типизированный объект c # из объекта json с ID как имя
  • Дезициализация свойств самореференции не работает
  • Линейная сериализация и де-сериализация
  • Как я могу зашифровать выбранные свойства при сериализации моих объектов?
  • JSON.NET и nHibernate Lazy Загрузка коллекций
  • Использование JSON.NET в качестве стандартного JSON-сериализатора в ASP.NET MVC 3 - возможно ли это?
  • Json.Net: свойство Serialize / Deserialize в качестве значения, а не как объект
  • Как программно выбирать конструктор во время десериализации?
  • Не удалось загрузить файл или сборку «Newtonsoft.Json» или одну из его зависимостей. Определение манифеста не соответствует ссылке на сборку
  • Обнаружен цикл саморегуляции - Возврат данных из WebApi в браузер
  • Как десериализовать объект JObject для .NET
  • Давайте будем гением компьютера.