Json.NET и общие словари - PullRequest
       21

Json.NET и общие словари

0 голосов
/ 11 августа 2010

Кажется невозможным (де) сериализовать универсальный словарь с использованием Json.NET из коробки.

class KeyClass
{
    public KeyClass(string p1, string p2) { prop1 = p1; prop2 = p2;}
    public string prop1 { get; set; }
    public string prop2 { get; set; }
}

class ValueClass
{
    public ValueClass(string pa, string pb) { propA = pa; propB = pb;}
    public string propA { get; set; }
    public string propB { get; set; }
}

...

Dictionary<KeyClass, ValueClass> d = new Dictionary<KeyClass, ValueClass>();
d.Add(new KeyClass("k1", "k2"), new ValueClass("v1", "v2"));
d.Add(new KeyClass("k3", "k4"), new ValueClass("v3", "v4"));
string json = JsonConvert.SerializeObject(d);

возвращает

{"ConsoleApplication1.KeyClass":{"propA":"v1","propB":"v2"},
 "ConsoleApplication1.KeyClass":{"propA":"v3","propB":"v4"}}

, где я ожидал что-то вроде:

{{"prop1":"k1","prop2":"k2"}:{"propA":"v1","propB":"v2"},
 {"prop1":"k3","prop2":"k4"}:{"propA":"v3","propB":"v4"}}

Итак, ToString() вызывается для ключа (KeyClass). (переопределение, которое генерирует JSON, не помогает: избегает JSON и просто не чувствует себя хорошо).

Можно ли написать CustomCreationConverter для этого случая?
Это ограничение hard для json.NET?
Если так, другие библиотеки поддерживают это?

1 Ответ

1 голос
/ 11 августа 2010

То, что вы пытаетесь сделать, не поддерживается в JSON, оно имеет мало общего с JSON.NET: «словарь» (он называется объектом в JSON) должен всегда иметь строковые ключи. Просто посмотрите на спецификации JSON .

То, что здесь делает JSON.NET, - это «правильный» способ обработки словаря C # (другой способ - выдать ошибку).

Обратите внимание, что JavaScript (из которых JSON является очень ограниченным подмножеством) также не допускает предложенный вами синтаксис.

Один из способов сериализации универсального словаря (или неуниверсальных словарей с нестроковыми ключами) заключается в сериализации его в виде списка пар ключ-значение, например,

[ { "key": {"prop1":"k1","prop2":"k2"}, "value": {"propA":"v1","propB":"v2"} },
  { "key": {"prop1":"k3","prop2":"k4"}, "value": {"propA":"v3","propB":"v4"} } ]

Как это сделать с JSON.NET - другое дело, но если это возможно, вы можете попытаться представить словарь как IEnumerable<KeyValuePair<X,Y>>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...