У меня есть дерево объектов, которое я сериализую в 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
все еще вызывается. Что может происходить из-за того, что мне не хватает?
Обновление: Ответы и комментарии, которые я получаю до сих пор, в значительной степени предлагают только обходные пути.Я отметил, однако, что у меня есть обходной путь, который работает довольно хорошо, поэтому, задавая этот вопрос, у меня две цели:
В конечном итоге заставить его работать с исходным дизайном - и я не собираюсь менять логику сериализации только для этого, от него зависит много кода и логики
. Чтобы понять тайну того, почему DataContractJsonSerializer
не использует мой код сериализации - как можно увидеть в сообщении блога, на которое я ссылался, я сделал всевозможные эксперименты с реализацией интерфейса и наследованием, и я был уверен, что понимаю все тонкости процесса, поэтому меня беспокоит непонимание того, что происходит в этом случае