Respostas:
Serializar estruturas de dados contendo apenas valores numéricos ou booleanos é bastante simples. Se você não tiver muito o que serializar, poderá escrever um método para seu tipo específico.
Para a Dictionary<int, List<int>>
como você especificou, você pode usar o 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) + "}";
}
Mas, se você estiver serializando várias classes diferentes, ou estruturas de dados mais complexas, ou especialmente se seus dados contiverem valores de sequência , seria melhor usar uma biblioteca JSON respeitável que já saiba lidar com coisas como caracteres de escape e quebras de linha. Json.NET é uma opção popular.
Esta resposta menciona o Json.NET, mas deixa de lhe dizer como você pode usar o Json.NET para serializar um dicionário:
return JsonConvert.SerializeObject( myDictionary );
Ao contrário do JavaScriptSerializer, myDictionary
não precisa ser um dicionário do tipo <string, string>
para o JsonConvert funcionar.
O Json.NET provavelmente serializa dicionários de C # adequadamente agora, mas quando o OP postou originalmente essa pergunta, muitos desenvolvedores do MVC podem estar usando a classe JavaScriptSerializer porque essa era a opção padrão pronta para uso.
Se você estiver trabalhando em um projeto legado (MVC 1 ou MVC 2) e não puder usar o Json.NET, recomendo usar um em List<KeyValuePair<K,V>>
vez de a Dictionary<K,V>>
. A classe herdada JavaScriptSerializer serializará esse tipo muito bem, mas terá problemas com um dicionário.
Documentation: Serializando coleções com o 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()));
}
}
}
}
Isso gravará no console:
[{\"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
)
Este código irá converter qualquer Dictionary<Key,Value>
para Dictionary<string,string>
e, em seguida, serializá-lo como uma string JSON:
var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));
Vale a pena notar que algo assim Dictionary<int, MyClass>
também pode ser serializado dessa maneira, preservando o tipo / objeto complexo.
var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.
Você pode substituir a variável yourDictionary
pela sua variável real.
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.
Fazemos isso, porque a chave e o valor precisam ser do tipo string, como requisito para serialização de 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
não está na versão Client Framework, mas requer a versão completa também.
Desculpe se a sintaxe está um pouquinho menor, mas o código do qual estou obtendo estava originalmente no 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);
No uso do Asp.net Core:
using Newtonsoft.Json
var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);
System.Core
e tentei referenciar using Newtonsoft.Json
e sem alegria. Eu acho que Newtonsoft
é uma biblioteca de terceiros.
Veja como fazê-lo usando apenas bibliotecas .Net padrão da 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>
e ter todos os tipos primitivos JSON, como intergers, floats, booleanos, strings e até nulos e dentro de um objeto. +1
Você poderia usar JavaScriptSerializer .
string
. Postei aqui uma resposta que inclui isso, se você quiser dar uma olhada.
Parece muitas bibliotecas diferentes e o que parece não ter surgido nos anos anteriores. No entanto, em abril de 2016, essa solução funcionou bem para mim. Strings facilmente substituídos por ints .
//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();
}
Dois pontos de importação. Primeiro, certifique-se de adicionar System.Runtime.Serliazation como referência no seu projeto no Solution Explorer do Visual Studio. Segundo, adicione esta linha,
using System.Runtime.Serialization.Json;
na parte superior do arquivo, com o restante de seus usos, para que a DataContractJsonSerializer
classe seja encontrada. Esta postagem do blog tem mais informações sobre esse método de serialização.
Meus dados são um dicionário com três strings, cada um apontando para uma lista de strings. As listas de cadeias têm comprimentos 3, 4 e 1. Os dados são assim:
StringKeyofDictionary1 => ["abc","def","ghi"]
StringKeyofDictionary2 => ["String01","String02","String03","String04"]
Stringkey3 => ["someString"]
A saída gravada no arquivo estará em uma linha, aqui está a saída formatada:
[{
"Key": "StringKeyofDictionary1",
"Value": ["abc",
"def",
"ghi"]
},
{
"Key": "StringKeyofDictionary2",
"Value": ["String01",
"String02",
"String03",
"String04",
]
},
{
"Key": "Stringkey3",
"Value": ["SomeString"]
}]
Isso é semelhante ao que Meritt postou anteriormente. apenas postando o código completo
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;
}
Se o seu contexto permitir (restrições técnicas, etc.), use o JsonConvert.SerializeObject
método da Newtonsoft.Json : facilitará sua vida.
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"}