Ответы:
Сериализация структур данных, содержащих только числовые или логические значения , довольно проста. Если вам нечего сериализовать, вы можете написать метод для вашего конкретного типа.
Для а 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, для работы JsonConvert myDictionary
не обязательно должен быть словарь типа <string, string>
.
Json.NET, вероятно, сейчас адекватно сериализует словари C #, но когда OP изначально разместил этот вопрос, многие разработчики MVC, возможно, использовали класс JavaScriptSerializer, потому что это был вариант по умолчанию из коробки.
Если вы работаете над устаревшим проектом (MVC 1 или MVC 2) и не можете использовать Json.NET, я рекомендую вам использовать List<KeyValuePair<K,V>>
вместо Dictionary<K,V>>
. Унаследованный класс JavaScriptSerializer отлично сериализует этот тип, но у него будут проблемы со словарем.
Документация: сериализация коллекций с помощью Json.NET
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]}]
( 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, как требование для сериализации a 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.
System.Web.Extensions
не в версии Client Framework, но также требует полной версии.
Извините, если синтаксис малюсенький, но код, который я получил, изначально был в 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.Core
а затем попытался сослаться using Newtonsoft.Json
и без радости. Думаю Newtonsoft
, это сторонняя библиотека.
Вот как это сделать, используя только стандартные библиотеки .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());
}
Dictionary<string, dynamic>
всеми примитивными типами JSON, такими как промежуточные числа, числа с плавающей запятой, логические значения, строки и даже нули, и иметь в одном объекте. +1
Вы можете использовать JavaScriptSerializer .
string
. Я опубликовал здесь ответ, который включает это, если вы хотите посмотреть.
Кажется, много разных библиотек и то, что не появилось и не исчезло за предыдущие годы. Однако по состоянию на апрель 2016 года это решение меня устраивало. Строки легко заменяются на целые .
//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.Serliazation в качестве ссылки в свой проект в обозревателе решений 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;
}
Если ваш контекст позволяет это (технические ограничения и т. Д.), Используйте 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"}