Non in grado di serializzare il dizionario con la chiave complessa usando Json.net

Ho un dizionario con un tipo .net personalizzato come chiave. Sto provando a serializzare questo dizionario su JSON usando JSON.net, ma non è in grado di convertire le chiavi in ​​valore corretto durante la serializzazione.

class ListBaseClass { public String testA; public String testB; } ----- var details = new Dictionary(); details.Add(new ListBaseClass { testA = "Hello", testB = "World" }, "Normal"); var results = Newtonsoft.Json.JsonConvert.SerializeObject(details); var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary> results); 

Questo Dammi -> “{\” JSonSerialization.ListBaseClass \ “: \” Normal \ “}”

Tuttavia se ho il mio tipo personalizzato come valore nel dizionario funziona bene

  var details = new Dictionary(); details.Add("Normal", new ListBaseClass { testA = "Hello", testB = "World" }); var results = Newtonsoft.Json.JsonConvert.SerializeObject(details); var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary>(results); 

Questo Give me -> “{\” Normal \ “: {\” testA \ “: \” Hello \ “, \” testB \ “: \” Mondo \ “}}”

Qualcuno può suggerire se sto colpendo qualche limitazione di Json.net o sto facendo qualcosa di sbagliato?

Gli stati della guida alla serializzazione (vedere la sezione: dizionari e hashtables, grazie a @Shashwat per il collegamento):

Durante la serializzazione di un dizionario, le chiavi del dizionario vengono convertite in stringhe e utilizzate come nomi di proprietà dell’object JSON. La stringa scritta per una chiave può essere personalizzata sovrascrivendo ToString () per il tipo di chiave o implementando un TypeConverter. Un TypeConverter supporta anche la conversione di una stringa personalizzata di nuovo quando deserializza un dizionario.

Ho trovato un esempio utile su come implementare un convertitore di questo tipo nella pagina “how-to” di Microsoft:

  • Implementare un convertitore di tipi (vedere la sezione Convertitori di tipi per la conversione del valore).

Essenzialmente, avevo bisogno di estendere System.ComponentModel.TypeConverter e sovrascrivere:

 bool CanConvertFrom(ITypeDescriptorContext context, Type source); object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value); object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType); 

Era anche necessario aggiungere l’attributo [TypeConverter(typeof(MyClassConverter))] alla dichiarazione della class MyClass .

Con questi strumenti, sono stato in grado di serializzare e deserializzare automaticamente i dizionari.

Tutto è più facile

 var details = new Dictionary(); details.Add("Normal", new ListBaseClass { testA = "Hello", testB = "World" }); var results = Newtonsoft.Json.JsonConvert.SerializeObject(details.ToList()); var data = Newtonsoft.Json.JsonConvert.DeserializeObject> results); 

Campione

  class Program { static void Main(string[] args) { var testDictionary = new Dictionary() { { new TestKey() { TestKey1 = "1", TestKey2 = "2", TestKey5 = 5 }, new TestValue() { TestValue1 = "Value", TestValue5 = 96 } } }; var json = JsonConvert.SerializeObject(testDictionary); Console.WriteLine("=== Dictionary =="); Console.WriteLine(json); // result: {"ConsoleApp2.TestKey":{"TestValue1":"Value","TestValue5":96}} json = JsonConvert.SerializeObject(testDictionary.ToList()); Console.WriteLine("=== List> =="); Console.WriteLine(json); // result: [{"Key":{"TestKey1":"1","TestKey2":"2","TestKey5":5},"Value":{"TestValue1":"Value","TestValue5":96}}] Console.ReadLine(); } } class TestKey { public string TestKey1 { get; set; } public string TestKey2 { get; set; } public int TestKey5 { get; set; } } class TestValue { public string TestValue1 { get; set; } public int TestValue5 { get; set; } }