Десериализация строки в словарь, содержащий объект

#c# #json #dictionary #serialization #deserialization

#c# #json #словарь #сериализация #десериализация

Вопрос:

У меня есть словарь, объявленный следующим образом:

 IDictionary<string, Rectangle> myitems = new Dictionary<string, Rectangle>();

// Populate with items
myitems["aaa"] = new Rectangle(10, 20, 30, 40);
myitems["bbb"] = new Rectangle(13, 34, 13, 232);
 

Я могу сериализовать его, выполнив это:

 string MyDictionaryToJson(IDictionary<string, Rectangle> dict)
{
    var entries = dict.Select(d =>
    string.Format(""{0}": [{1}]", d.Key, string.Join(",", d.Value)));
    return "{"   string.Join(",", entries)   "}";
}

String serializedItems = MyDictionaryToJson(myitems);
 

Моя проблема в том, что я не могу найти способ сделать обратное и преобразовать сериализованную строку обратно
в мой словарь. Я стараюсь не использовать никаких дополнительных библиотек, но я даже после попытки этого:

 Dictionary<string, Rectangle> mynewdic = JsonConvert.DeserializeObject<Dictionary<string, Rectangle>>(myitems);
 

по-прежнему не работает.

Есть идеи?

Комментарии:

1. Вы создаете json вручную, но надеетесь, что newtonsoft deser это? Рассматривали ли вы возможность использования newtonsoft как ser, так и deser? Вы смотрели на пользовательский de / ser ? Рассматривали ли вы возможность использования LINQ для проецирования вашего словаря на анонимный тип string , int[], а также для удаления этого / удаления и проецирования обратно в dict ?

2. «Метод, противоположный» должен быть в первом комментарии

Ответ №1:

Итак, вы пытаетесь преобразовать некоторый конкретный класс в пользовательский массив json.

Обычно вы делаете это с помощью JsonConverter

Учитывая

 public class RectangleConverter : JsonConverter<Rectangle>
{
   public override void WriteJson(JsonWriter writer, Rectangle value, JsonSerializer serializer)
   {
      var array = new JArray {value.X, value.Y, value.Top, value.Bottom};
      array.WriteTo(writer);
   }
   
   public override Rectangle ReadJson(JsonReader reader, Type objectType, Rectangle existingValue, bool hasExistingValue, JsonSerializer serializer)
   {
      var s = JArray.Load(reader);
      return new Rectangle(int.Parse(s[0].ToObject<string>()),int.Parse(s[1].ToObject<string>()),int.Parse(s[2].ToObject<string>()),int.Parse(s[3].ToObject<string>()));

   }
}
 

Пример использования

 var myitems = new Dictionary<string, Rectangle>();
myitems["aaa"] = new Rectangle(10, 20, 30, 40);
myitems["bbb"] = new Rectangle(13, 34, 13, 232);

Console.WriteLine("Original Dictionary");
foreach (var item in myitems)
   Console.WriteLine(item);

var json = JsonConvert.SerializeObject(myitems, Formatting.Indented, new RectangleConverter());
Console.WriteLine();
Console.WriteLine("Serialized data");
Console.WriteLine(json);

var result = JsonConvert.DeserializeObject<Dictionary<string, Rectangle>>(json, new RectangleConverter());

Console.WriteLine();
Console.WriteLine("Recreated Dictionary");
   foreach (var item in result)
      Console.WriteLine(item);
 

Вывод

 Original Dictionary
[aaa, {X=10,Y=20,Width=30,Height=40}]
[bbb, {X=13,Y=34,Width=13,Height=232}]

Serialized data
{
  "aaa": [
    10,
    20,
    30,
    40
  ],
  "bbb": [
    13,
    34,
    13,
    232
  ]
}

Recreated Dictionary
[aaa, {X=10,Y=20,Width=30,Height=40}]
[bbb, {X=13,Y=34,Width=13,Height=232}]
 

Примечание: В этом ответе конкретно рассматривается, как вы можете преобразовать конкретный класс в массив (и обратно), как вам нужны данные, отформатированные (в каком порядке), не относится к этому ответу, я оставлю эти детали на ваше усмотрение.