Сериализовать словарь в JSON с помощью DataContractJsonSerializer

У меня есть дерево объектов, которое я сериализую в JSON с помощью DataContractJsonSerializer . Dictionary сериализуется, но мне не нравится разметка - элементы отображаются не так:

{key1:value, key2:value2}

, а скорее как массив сериализованных KeyValuePair объекты:

[{
    "__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
    "key":"key1",
    "value":"value1"
 },     
 {
    "__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
    "key":"key2",
    "value":"value2"
 }]

Уродливо, не правда ли?

Я избегаю этого, заключая общий словарь в специальный объект, реализующий ISerializable , и реализую свою настраиваемую сериализацию в GetObjectData (а занимает всего 3 строки).

Теперь проблема - я не могу сделать свой класс производным от Dictionary , поэтому я реализую всю логику ( Add , Clear и т. д.) в моем настраиваемом классе, применяемом к частному полю Dictionary . Наследование было бы предпочтительнее, поскольку при использовании моего настраиваемого объекта в моем распоряжении будут все общие функции словаря.

Проблема с наследованием заключается в том, что Dictionary реализует ISerializable самостоятельно, а DataContractJsonSerializer , похоже, предпочитает эту реализацию, даже если я реализую ISerializable явно из моего пользовательского класса, например:

public class MyClass : Dictionary, ISerializable
{
    public override void GetObjectData(SerializationInfo info, 
        StreamingContext context)
}

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

Итак, согласно экспериментам, которые я там проводил, сериализатор должен вызывать мою реализацию ISerializable, независимо от того, какой тип преобразования используется внутри -

((ISerializable)((Dictionary<,>)obj)).GetObjectData(...)

или:

((ISerializable)obj).GetObjectData(...)

, но, по-видимому, этого не происходит, поскольку в полученном JSON я вижу, что сериализатор KeyValuePair все еще вызывается. Что может происходить из-за того, что мне не хватает?

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

  1. В конечном итоге заставить его работать с исходным дизайном - и я не собираюсь менять логику сериализации только для этого, от него зависит много кода и логики

  2. . Чтобы понять тайну того, почему DataContractJsonSerializer не использует мой код сериализации - как можно увидеть в сообщении блога, на которое я ссылался, я сделал всевозможные эксперименты с реализацией интерфейса и наследованием, и я был уверен, что понимаю все тонкости процесса, поэтому меня беспокоит непонимание того, что происходит в этом случае

15
задан dbc 9 August 2017 в 22:37
поделиться