Как преобразовать словарь в строку JSON в C#?
Я хочу преобразовать мой Dictionary<int,List<int>>
в строку JSON. Кто-нибудь знает, как этого добиться в C#?
16 ответов
Сериализация структур данных, содержащих только числовые или логические значения, довольно проста. Если вам нечего сериализировать, вы можете написать метод для вашего конкретного типа.
Для 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 является популярным вариантом.
В этом ответе упоминается Json.NET, но не сказано, как вы можете использовать Json.NET для сериализации словаря:
return JsonConvert.SerializeObject( myDictionary );
В отличие от JavaScriptSerializer, myDictionary
не обязательно должен быть словарь типа <string, string>
чтобы JsonConvert работал.
Json.NET, вероятно, теперь адекватно сериализует словари C#, но когда ОП первоначально разместил этот вопрос, многие разработчики MVC, возможно, использовали класс JavaScriptSerializer, потому что это был стандартный вариант по умолчанию.
Если вы работаете над устаревшим проектом (MVC 1 или MVC 2) и не можете использовать Json.NET, я рекомендую вам использовать List<KeyValuePair<K,V>>
вместо Dictionary<K,V>>
, Устаревший класс JavaScriptSerializer отлично сериализует этот тип, но у него будут проблемы со словарем.
Документация: Сериализация коллекций с помощью Json.NET
Простой однострочный ответ
(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.
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]}]
Если ваш контекст позволяет это (технические ограничения и т. Д.), Используйте JsonConvert.SerializeObject
метод от Newtonsoft.Json: он облегчит вашу жизнь.
Dictionary<string, string> localizedWelcomeLabels = new Dictionary<string, string>();
localizedWelcomeLabels.Add("en", "Welcome");
localizedWelcomeLabels.Add("fr", "Bienvenue");
localizedWelcomeLabels.Add("de", "Willkommen");
Console.WriteLine(JsonConvert.SerializeObject(localizedWelcomeLabels));
// Outputs : {"en":"Welcome","fr":"Bienvenue","de":"Willkommen"}
Извините, если синтаксис самый малюсенький, но код, который я получил, изначально был на 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);
В Asp.net Core используют:
using Newtonsoft.Json
var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
сетевое ядро: System.Text.Json.JsonSerializer.Serialize(dict)
Ты можешь использовать 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);
Вот как это сделать, используя только стандартные библиотеки.Net от Microsoft …
using System.IO;
using System.Runtime.Serialization.Json;
private static string DataToJson<T>(T data)
{
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer serialiser = new DataContractJsonSerializer(
data.GetType(),
new DataContractJsonSerializerSettings()
{
UseSimpleDictionaryFormat = true
});
serialiser.WriteObject(stream, data);
return Encoding.UTF8.GetString(stream.ToArray());
}
Кажется, много разных библиотек и то, что не появилось и не появилось за предыдущие годы. Однако по состоянию на апрель 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"]
}]
Это похоже на то, что Меритт опубликовал ранее. просто опубликовать полный код
string sJSON;
Dictionary<string, string> aa1 = new Dictionary<string, string>();
aa1.Add("one", "1"); aa1.Add("two", "2"); aa1.Add("three", "3");
Console.Write("JSON form of Person object: ");
sJSON = WriteFromObject(aa1);
Console.WriteLine(sJSON);
Dictionary<string, string> aaret = new Dictionary<string, string>();
aaret = ReadToObject<Dictionary<string, string>>(sJSON);
public static string WriteFromObject(object obj)
{
byte[] json;
//Create a stream to serialize the object to.
using (MemoryStream ms = new MemoryStream())
{
// Serializer the object to the stream.
DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
ser.WriteObject(ms, obj);
json = ms.ToArray();
ms.Close();
}
return Encoding.UTF8.GetString(json, 0, json.Length);
}
// Deserialize a JSON stream to object.
public static T ReadToObject<T>(string json) where T : class, new()
{
T deserializedObject = new T();
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedObject.GetType());
deserializedObject = ser.ReadObject(ms) as T;
ms.Close();
}
return deserializedObject;
}
Для справки, среди всех старых решений: UWP имеет собственную встроенную библиотеку JSON,
Windows.Data.Json
.
JsonObject
это карта, которую вы можете использовать напрямую для хранения ваших данных:
var options = new JsonObject();
options["foo"] = JsonValue.CreateStringValue("bar");
string json = options.ToString();
улучшенная версия mwjohnson:
string WriteDictionaryAsJson_v2(Dictionary<string, List<string>> myDict)
{
string str_json = "";
DataContractJsonSerializerSettings setting =
new DataContractJsonSerializerSettings()
{
UseSimpleDictionaryFormat = true
};
DataContractJsonSerializer js =
new DataContractJsonSerializer(typeof(Dictionary<string, List<string>>), setting);
using (MemoryStream ms = new MemoryStream())
{
// Serializer the object to the stream.
DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
ser.WriteObject(ms, myDict);
str_json = Encoding.Default.GetString(ms.ToArray());
}
return str_json;
}