Как преобразовать словарь в строку JSON в C #? - PullRequest
113 голосов
/ 08 апреля 2011

Я хочу преобразовать мою Dictionary<int,List<int>> в строку JSON.Кто-нибудь знает, как этого добиться в C #?

Ответы [ 11 ]

109 голосов
/ 08 апреля 2011

Сериализация структур данных , содержащих только числовые или логические значения , довольно проста.Если вам нечего сериализовать, вы можете написать метод для вашего конкретного типа.

Для Dictionary<int, List<int>>, как вы указали, вы можете использовать Linq:

string MyDictionaryToJson(Dictionary<int, List<int>> dict)
{
    var entries = dict.Select(d =>
        string.Format("\"{0}\": [{1}]", d.Key, string.Join(",", d.Value)));
    return "{" + string.Join(",", entries) + "}";
}

Но если вы сериализуете несколько различных классов или более сложные структуры данных, или особенно если ваши данные содержат строковые значения , вам лучше использовать авторитетную библиотеку JSON, которая уже знаеткак обрабатывать такие вещи, как escape-символы и разрывы строк. Json.NET является популярным вариантом.

75 голосов
/ 12 сентября 2014

В этом ответе упоминается Json.NET, но не сказано, как использовать Json.NET для сериализации словаря:

return JsonConvert.SerializeObject( myDictionary );

В отличие от JavaScriptSerializer, myDictionaryдля работы JsonConvert не обязательно должен быть словарь типа <string, string>.

70 голосов
/ 07 декабря 2012

Json.NET , вероятно, теперь адекватно сериализует словари C #, но когда ОП первоначально разместил этот вопрос, многие разработчики MVC, возможно, использовали класс JavaScriptSerializer , потому что это был параметр по умолчаниюиз коробки.

Если вы работаете над устаревшим проектом (MVC 1 или MVC 2) и не можете использовать Json.NET, я рекомендую использовать List<KeyValuePair<K,V>> вместоDictionary<K,V>>.Унаследованный класс JavaScriptSerializer отлично сериализует этот тип, но у него будут проблемы со словарем.

Документация: Сериализация коллекций с помощью Json.NET

18 голосов
/ 08 апреля 2011
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Json;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, List<int>> foo = new Dictionary<int, List<int>>();

            foo.Add(1, new List<int>( new int[] { 1, 2, 3, 4 }));
            foo.Add(2, new List<int>(new int[] { 2, 3, 4, 1 }));
            foo.Add(3, new List<int>(new int[] { 3, 4, 1, 2 }));
            foo.Add(4, new List<int>(new int[] { 4, 1, 2, 3 }));

            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<int, List<int>>));

            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, foo);
                Console.WriteLine(Encoding.Default.GetString(ms.ToArray()));
            }
        }
    }
}

Это запишет в консоль:

[{\"Key\":1,\"Value\":[1,2,3,4]},{\"Key\":2,\"Value\":[2,3,4,1]},{\"Key\":3,\"Value\":[3,4,1,2]},{\"Key\":4,\"Value\":[4,1,2,3]}]
12 голосов
/ 07 июля 2014

Простой однострочный ответ

(using System.Web.Script.Serialization)

Этот код преобразует любой Dictionary<Key,Value> в Dictionary<string,string> и затем сериализует его в виде строки JSON:

var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));

Стоит отметить, что что-то вроде Dictionary<int, MyClass> также может быть сериализовано таким образом, сохраняя сложный тип / объект.


Объяснение (разбивка)

var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.

Вы можете заменить переменную yourDictionary фактической переменной.

var convertedDictionary = yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()); //This converts your dictionary to have the Key and Value of type string.

Мы делаем это, потому что ключ и значение должны иметь тип string, как требование для сериализации Dictionary.

var json = new JavaScriptSerializer().Serialize(convertedDictionary); //You can then serialize the Dictionary, as both the Key and Value is of type string, which is required for serialization.
12 голосов
/ 08 апреля 2011

Извините, если синтаксис самый малюсенький, но код, который я получил, изначально был в VB:)

using System.Web.Script.Serialization;

...

Dictionary<int,List<int>> MyObj = new Dictionary<int,List<int>>();

//Populate it here...

string myJsonString = (new JavaScriptSerializer()).Serialize(MyObj);
7 голосов
/ 18 февраля 2015

Вы можете использовать System.Web.Script.Serialization.JavaScriptSerializer:

Dictionary<string, object> dictss = new Dictionary<string, object>(){
   {"User", "Mr.Joshua"},
   {"Pass", "4324"},
};

string jsonString = (new JavaScriptSerializer()).Serialize((object)dictss);
5 голосов
/ 15 октября 2016

В Asp.net Core используют:

using Newtonsoft.Json

var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
1 голос
/ 27 апреля 2016

Кажется, много разных библиотек и то, что, похоже, не приходило и не уходило в предыдущие годы.Однако по состоянию на апрель 2016 года это решение работало хорошо для меня. Струны легко заменяются на целые .

TL / DR;Скопируйте это, если вы пришли сюда:

    //outputfilename will be something like: "C:/MyFolder/MyFile.txt"
    void WriteDictionaryAsJson(Dictionary<string, List<string>> myDict, string outputfilename)
    {
        DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Dictionary<string, List<string>>));
        MemoryStream ms = new MemoryStream();
        js.WriteObject(ms, myDict); //Does the serialization.

        StreamWriter streamwriter = new StreamWriter(outputfilename);
        streamwriter.AutoFlush = true; // Without this, I've run into issues with the stream being "full"...this solves that problem.

        ms.Position = 0; //ms contains our data in json format, so let's start from the beginning
        StreamReader sr = new StreamReader(ms); //Read all of our memory
        streamwriter.WriteLine(sr.ReadToEnd()); // and write it out.

        ms.Close(); //Shutdown everything since we're done.
        streamwriter.Close();
        sr.Close();
    }

Две точки импорта.Во-первых, обязательно добавьте System.Runtime.Serliaization в качестве ссылки в свой проект в обозревателе решений Visual Studio.Во-вторых, добавьте эту строку,

using System.Runtime.Serialization.Json;

в верхней части файла с остальными значениями, чтобы можно было найти класс DataContractJsonSerializer.Это сообщение в блоге содержит больше информации об этом методе сериализации.

Формат данных (ввод / вывод)

Мои данные - это словарь с 3 строками, каждая из которых указывает насписок строк.Списки строк имеют длину 3, 4 и 1. Данные выглядят так:

StringKeyofDictionary1 => ["abc","def","ghi"]
StringKeyofDictionary2 => ["String01","String02","String03","String04"]
Stringkey3 => ["someString"]

Вывод, записанный в файл, будет в одну строку, вот форматированный вывод:

 [{
     "Key": "StringKeyofDictionary1",
     "Value": ["abc",
     "def",
     "ghi"]
 },
 {
     "Key": "StringKeyofDictionary2",
     "Value": ["String01",
     "String02",
     "String03",
     "String04",
 ]
 },
 {
     "Key": "Stringkey3",
     "Value": ["SomeString"]
 }]
1 голос
/ 08 апреля 2011

Вы можете использовать JavaScriptSerializer .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...