Chcę przekonwertować mój Dictionary<int,List<int>>
ciąg na JSON. Czy ktoś wie, jak to osiągnąć w C #?
c#
json
dictionary
daehaai
źródło
źródło
Odpowiedzi:
Serializacja struktur danych zawierających tylko wartości liczbowe lub logiczne jest dość prosta. Jeśli nie masz zbyt wiele do serializacji, możesz napisać metodę dla określonego typu.
Przez
Dictionary<int, List<int>>
co podałeś, można użyć 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) + "}"; }
Ale jeśli serializujesz kilka różnych klas lub bardziej złożone struktury danych, a zwłaszcza jeśli dane zawierają wartości ciągów , lepiej byłoby użyć renomowanej biblioteki JSON, która już wie, jak obsługiwać takie rzeczy, jak znaki ucieczki i podziały wierszy. Json.NET to popularna opcja.
źródło
Ta odpowiedź wspomina o Json.NET, ale nie mówi, jak można użyć Json.NET do serializacji słownika:
return JsonConvert.SerializeObject( myDictionary );
W przeciwieństwie do JavaScriptSerializer
myDictionary
nie musi być słownikiem typu,<string, string>
aby JsonConvert działał.źródło
Json.NET prawdopodobnie odpowiednio serializuje słowniki C #, ale kiedy OP pierwotnie opublikował to pytanie, wielu programistów MVC mogło używać klasy JavaScriptSerializer, ponieważ była to domyślna opcja.
Jeśli pracujesz nad starszym projektem (MVC 1 lub MVC 2) i nie możesz używać Json.NET, zalecam użycie pliku
List<KeyValuePair<K,V>>
zamiastDictionary<K,V>>
. Starsza klasa JavaScriptSerializer będzie mogła serializować ten typ dobrze, ale będzie miała problemy ze słownikiem.Dokumentacja: serializowanie kolekcji za pomocą Json.NET
źródło
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())); } } } }
To napisze do konsoli:
[{\"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]}]
źródło
Prosta odpowiedź w jednej linii
(
using System.Web.Script.Serialization
)Ten kod skonwertuje wszystkie
Dictionary<Key,Value>
na,Dictionary<string,string>
a następnie serializuje je jako ciąg JSON:var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));
Warto zauważyć, że coś podobnego
Dictionary<int, MyClass>
można również serializować w ten sposób, zachowując złożony typ / obiekt.Wyjaśnienie (podział)
var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.
Możesz zastąpić zmienną
yourDictionary
swoją rzeczywistą zmienną.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.
Robimy to, ponieważ zarówno klucz, jak i wartość muszą być typu string, jako wymaganie do serializacji pliku
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.
źródło
System.Web.Extensions
nie ma go w wersji Client Framework, ale wymaga też pełnej wersji.Przepraszam, jeśli składnia jest najmniejsza, ale kod, z którego to otrzymuję, był pierwotnie w 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);
źródło
W Asp.net Core użyj:
using Newtonsoft.Json var obj = new { MyValue = 1 }; var json = JsonConvert.SerializeObject(obj); var obj2 = JsonConvert.DeserializeObject(json);
źródło
System.Core
a potem próbowałem odwołać sięusing Newtonsoft.Json
i bez radości. Myślę, żeNewtonsoft
jest to biblioteka innej firmy.Możesz użyć
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);
źródło
Oto jak to zrobić, używając tylko standardowych bibliotek .Net firmy 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()); }
źródło
Dictionary<string, dynamic>
i mieć wszystkie prymitywne typy JSON, takie jak intergers, floats, booleans, stringi, a nawet null w jednym obiekcie. +1Możesz użyć JavaScriptSerializer .
źródło
string
. Opublikowałem tutaj odpowiedź, która zawiera to, jeśli chcesz zobaczyć.Wydaje się, że jest wiele różnych bibliotek, a to, co nie pojawiło się i nie pojawiło się w poprzednich latach. Jednak od kwietnia 2016 roku to rozwiązanie działało dobrze. Ciągi łatwo zastępowane przez int .
TL / DR; Skopiuj to, jeśli po to tu przyszedłeś:
//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(); }
Dwa punkty importu. Najpierw pamiętaj, aby dodać System.Runtime.Serliazation jako odniesienie w projekcie w Eksploratorze rozwiązań programu Visual Studio. Po drugie, dodaj tę linię,
using System.Runtime.Serialization.Json;
u góry pliku z resztą zastosowań, aby
DataContractJsonSerializer
można było znaleźć klasę. Ten wpis na blogu zawiera więcej informacji na temat tej metody serializacji.Format danych (wejście / wyjście)
Moje dane to słownik z 3 ciągami znaków, z których każdy wskazuje listę ciągów. Listy ciągów mają długości 3, 4 i 1. Dane wyglądają następująco:
StringKeyofDictionary1 => ["abc","def","ghi"] StringKeyofDictionary2 => ["String01","String02","String03","String04"] Stringkey3 => ["someString"]
Dane wyjściowe zapisane do pliku będą znajdować się w jednym wierszu, tutaj jest sformatowane wyjście:
[{ "Key": "StringKeyofDictionary1", "Value": ["abc", "def", "ghi"] }, { "Key": "StringKeyofDictionary2", "Value": ["String01", "String02", "String03", "String04", ] }, { "Key": "Stringkey3", "Value": ["SomeString"] }]
źródło
Jeśli pozwala na to kontekst (ograniczenia techniczne itp.), Użyj
JsonConvert.SerializeObject
metody z Newtonsoft.Json : ułatwi Ci to życie.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"}
źródło
Jest to podobne do tego, co opublikował wcześniej Meritt. po prostu zamieszczając cały kod
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; }
źródło