Chcę przekonwertować mój Dictionary<int,List<int>>
ciąg na JSON. Czy ktoś wie, jak to osiągnąć w C #?
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.
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ł.
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>>
zamiast Dictionary<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
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]}]
( 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.
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.
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);
W Asp.net Core użyj:
using Newtonsoft.Json
var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
System.Core
a potem próbowałem odwołać się using Newtonsoft.Json
i bez radości. Myślę, że Newtonsoft
jest to biblioteka innej firmy.
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());
}
Dictionary<string, dynamic>
i mieć wszystkie prymitywne typy JSON, takie jak intergers, floats, booleans, stringi, a nawet null w jednym obiekcie. +1
Możesz użyć JavaScriptSerializer .
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 .
//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.
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"]
}]
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"}
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;
}