Відповіді:
Серіалізація структур даних, що містять лише числові або булеві значення , досить проста. Якщо вам не потрібно багато серіалізувати, ви можете написати метод для вашого конкретного типу.
Для а 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, яка вже вміє обробляти такі речі, як символи втечі та розриви рядків. Json.NET - популярний варіант.
Ця відповідь згадує Json.NET, але не зупиняється на тому, як ви можете використовувати Json.NET для серіалізації словника:
return JsonConvert.SerializeObject( myDictionary );
На відміну від JavaScriptSerializer, для роботи JsonConvert myDictionary
не повинен бути словник типу <string, string>
.
Json.NET, ймовірно, зараз адекватно серіалізує словники C #, але коли ОР спочатку розмістила це запитання, багато розробників 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.
Ми робимо це, тому що і Ключ, і Значення повинні бути типів рядка, як вимоги до серіалізації а 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, такими як interger, floats, booleans, strings, навіть null і в межах одного об'єкта. +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.Serlialization як орієнтир у своєму проекті в Провіднику рішень 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"]
}]
Це схоже на те, що Meritt опублікував раніше. просто розміщуємо повний код
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"}