Tengo un árbol de objetos que estoy serializando en JSON con DataContractJsonSerializer
. Dictionary<TKey, TValue>
consigue serializado, pero no me gusta el margen de beneficio - los artículos no se representan así:Serialize Dictionary <TKey, TValue> a JSON con DataContractJsonSerializer
{key1:value, key2:value2}
sino más bien como un conjunto de objetos serializados KeyValuePair<TKey, TValue>
:
[{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key1",
"value":"value1"
},
{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key2",
"value":"value2"
}]
feo, no es lo ?
Así que evito esto envolviendo el Diccionario genérico en un objeto personalizado que implementa ISerializable
, e implemento mi serialización personalizada en el método GetObjectData
(y solo toma 3 líneas).
Ahora el problema - no puedo hacer que mi clase se derivan de Dictionary<TKey, TValue>
, así que implementar toda la lógica (Add
, Clear
, etc.) en mi clase personalizada, que se aplica a un campo privado Dictionary<TKey, TValue>
. La herencia sería preferible, ya que tendré toda la funcionalidad del Diccionario genérico a mi disposición cuando use mi objeto personalizado.
El problema con la herencia es que Dictionary<TKey, TValue>
implementa ISerializable
por su propia cuenta, y DataContractJsonSerializer
parece preferir esta aplicación incluso si implemento ISerializable
explícitamente de mi clase personalizada, así:
public class MyClass : Dictionary<string, object>, ISerializable
{
public override void GetObjectData(SerializationInfo info,
StreamingContext context)
}
Estaba realmente sorprendido de que esto es posible ya que me permite implementar la misma interfaz dos veces sin ser obviamente capaz de usar la implementación de interfaz explícita, así que analicé la situación con más detalle en una publicación de blog about multiple interface implementation
Así que, de acuerdo con los experimentos que hice allí, el serializador debe ser llamar a mi aplicación de ISerializable, no importa qué tipo de fundición se utiliza internamente -
((ISerializable)((Dictionary<,>)obj)).GetObjectData(...)
o:
((ISerializable)obj).GetObjectData(...)
pero al parecer no es sucediendo como veo en el JSON resultante que aún se llama al serializador KeyValuePair<TKey, TValue>
. ¿Qué podría estar pasando que me estoy perdiendo?
Actualización: Las respuestas y los comentarios que recibo hasta ahora son solo sugerencias de soluciones.Me ha señalado, sin embargo, que tengo una solución que funciona bastante bien por lo que con esta pregunta tengo 2 objetivos:
Eventualmente hacer que funcione con el diseño original - y yo no voy a cambiar la lógica de serialización solo por eso, hay un montón de código y lógica dependiente
Para entender el misterio de por qué no está el
DataContractJsonSerializer
usando mi código de serialización, como se puede ver en la publicación del blog que mencioné, hice todo tipo de experimentos con la implementación de la interfaz y la herencia, y estaba seguro de que comprendía todos los pormenores del proceso, así que me preocupa no entender lo que está pasando en este proceso. caso
Parece que podría envolver el diccionario con una clase IEnumerable y su implementación ISerializable. Mucho menos trabajo que tratar de heredar de un diccionario. –
También podría usar el 'JavaScriptSerializer' ya que serializa los diccionarios como prefiera. –
@RitchMelton: heredar del diccionario no es mucho trabajo, pero debo admitir que implementar IEnumerable y devolver el getEnumarator del diccionario miembro a primera vista parece ser mejor que mi solución alternativa: solo un método para implementar – Vroomfundel