2008-09-20 12 views
30

Me gustaría serializar y deserializar objetos sin tener que preocuparme por todo el gráfico de clase.¿Cuál es la serialización más flexible para objetos .NET, pero simple de implementar?

La flexibilidad es la clave. Me gustaría poder serializar cualquier objeto que se me pase sin los atributos completos necesarios en todo el gráfico de objetos.

Eso significa que la serialización binaria no es una opción, ya que sólo funciona con las otras plataformas .NET. Me gustaría también como algo legible por una persona , y por lo tanto descifrable por un programa de gestión y otros intérpretes .

He encontrado problemas al usar los Serializadores DataContract, JSON y XML.

  • La mayoría de estos errores parecen centrarse en la serialización de listas/diccionarios (es decir, XML Serializable Generic Dictionary).
  • "Añadir cualquier tipo no conocidos estáticamente a la lista de tipos conocidos - para ejemplo, mediante el atributo KnownTypeAttribute o añadirlos a la lista de tipos conocidos pasado a DataContractSerializer."

Por favor, base sus respuestas en las experiencias reales y no la teoría o la lectura de un artículo.

Respuesta

53

¿Ha considerado la serialización de JSON en lugar de XML?

Json.NET tiene un serializador realmente potente y flexible que no tiene problemas con los diccionarios Hashtables/genéricos y no requiere ningún atributo en particular. Lo sé porque lo escribí :)

Le da un montón de control a través de varias opciones en el serializador y le permite anular cómo se serializa un tipo creando un JsonConverter para él.

En mi opinión, JSON es más legible que XML y Json.NET ofrece la opción de escribir JSON con buen formato.

Finalmente, el proyecto es de código abierto, por lo que puede entrar en el código y hacer modificaciones si es necesario.

+0

He intentado esto, y me dio mejores resultados de error que el DataManinpulator JSON Serializer, pero aún así se dañó debido a una referencia de bucle. ¿Algún consejo? Estoy construyendo un marco de mensajería y no tengo mucho control sobre la estructura real de ningún objeto. – mrbradleyt

+1

Establezca la propiedad ReferenceLoopHandling en JsonSerializer en Ignore. –

+6

Yo uso JSON.Net - ¡¡¡¡totalmente rockero !!!!! –

0

Lo más simple es marcar sus objetos con el atributo Serializable y luego usar un formateador binario para manejar la serialización. El gráfico de clase completo no debería ser un problema siempre que cualquier objeto contenido también esté marcado como Serializable.

+0

No estaba seguro de si mrbradleyt quería ignorar algunas partes del gráfico de clase cuando dijo que no quería preocuparse por eso. En ese caso, no todos los atributos deben ser serializables (NonSerializedAttribute puede marcar campos que deberían ser excluidos) –

+0

Sí, señalado. También aclaró que necesita un formato no binario, por lo que mi solución no funcionaría para él. –

+0

El asker ha excluido específicamente la serialización binaria. –

1

El IntermediateSerializer en el XNA Framework es bastante genial. Usted puede encontrar un montón de tutoriales en usarlo en http://blogs.msdn.com/shawnhar

+0

Más específicamente, puedes encontrar todas las publicaciones de Shawn relacionadas con el serializador intermedio aquí: http://www.talula.demon.co.uk/blogindex.html#intermediateserializer –

1

serialización de SOAP funcionado bien para mí, incluso para objetos que no aparecen con [Serializable]

+0

¿Qué clase usas? – mrbradleyt

+0

Creo que el uso de la serialización SOAP no se recomienda desde NET 2.0. En realidad, ni siquiera maneja genéricos. http://social.msdn.microsoft.com/Forums/en-US/netfxremoting/thread/ee4a7a63-290e-432f-bd45-44f4cb7a3467/ –

+0

En algún lugar de Serialization.Formatters.Soap – ripper234

2

Desde sus requisitos suena como la serialización XML es mejor.

¿Qué tipo de problemas tiene con las colecciones al serializar? Si se refiere a no saber qué atributos usar en una Lista o algo similar, puede probar el atributo XmlArray en su propiedad. Definitivamente puede serializar una colección.

+0

¿Puede usted explicar con más detalle la XmlArray atributo ... estaba teniendo problemas con las listas .... – mrbradleyt

+0

Realmente no necesita el atributo XmlArray si usa sgen. El patrón general es derivar una clase separada de la lista , y luego serializar que en su lugar por ejemplo. [Serializable] public class YourObjectCollection: Lista {} Sin embargo, he encontrado que incluso eso no es necesario – ilitirit

+0

1 ilitirit. Se corrigió un problema molesto que tenía cuando no podía serializar una lista sin obtener un conjunto adicional de etiquetas que la envolvieran, por lo que no pude leerla en un DataSet. –

1

Tendrá problemas con la serialización de la colección si los objetos en la colección contienen alguna referencia a otros objetos en la misma colección. Si existe algún tipo de doble punteo, terminas creando un mapa múltiple que no se puede serializar. En todos los problemas que tuve al serializar una colección personalizada, siempre fue por alguna funcionalidad adicional que necesitaba que funcionaba bien como parte de una aplicación cliente-servidor "típica", y luego fracasaba miserablemente como parte de un proveedor de consumo aplicación de servidor.

1

Coloque todas las clases que desee serializar en un ensamblaje por separado, y luego use la herramienta sgen para generar un conjunto de serialización para serializar en XML. Use atributos XML para controlar la serialización.

Si necesita personalizar el ensamblado de serialización (y que se necesidad de que para apoyar las clases que no son IXmlSerializable y clases que contienen nodos abstractos), entonces instruir a sgen para volcar el código fuente en un archivo separado y luego agrégalo a tu solución. Entonces puedes modificarlo según sea necesario.

http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx

Fwiw, me las he arreglado para serializar todo el marco AdsML (más de 400 clases) usando esta técnica. Se requirió mucha personalización manual, pero no hay forma de evitarlo si se tiene en cuenta el tamaño del marco. (He utilizado una herramienta separada para ir de XSD para C#)

0

Tal vez una ruta más eficiente sería para serializar utilizando BinaryFormatter

Como copiado de http://blog.paranoidferret.com/index.php/2007/04/27/csharp-tutorial-serialize-objects-to-a-file/

using System.IO; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 

public class Serializer 
{ 
    public Serializer() 
    { 
    } 

    public void SerializeObject(string filename, 
        ObjectToSerialize objectToSerialize) 
    { 
     Stream stream = File.Open(filename, FileMode.Create); 
     BinaryFormatter bFormatter = new BinaryFormatter(); 
     bFormatter.Serialize(stream, objectToSerialize); 
     stream.Close(); 
    } 

    public ObjectToSerialize DeSerializeObject(string filename) 
    { 
     ObjectToSerialize objectToSerialize; 
     Stream stream = File.Open(filename, FileMode.Open); 
     BinaryFormatter bFormatter = new BinaryFormatter(); 
     objectToSerialize = 
     (ObjectToSerialize)bFormatter.Deserialize(stream); 
     stream.Close(); 
     return objectToSerialize; 
    } 
} 
0

Para la interoperabilidad siempre hemos utilizado la Serialización Xml y nos aseguramos de que nuestra clase se haya diseñado desde cero para hacerlo correctamente.

Creamos un documento de esquema XSD y generamos un conjunto de clases a partir de eso usando XSD.exe. Esto genera clases parciales, entonces creamos un conjunto de clases parciales correspondientes para agregar los métodos adicionales que queremos para ayudarnos a poblar las clases y usarlas en nuestra aplicación (ya que están enfocadas en la serialización y deserialización y son un poco difíciles de usar algunas veces)

0

Debe usar NetDataContractSerializer.Cubre todo tipo de gráfico de objetos y admite genéricos, listas, polimorfismo (el atributo KnownType no es necesario aquí), recursión, etc. El único inconveniente es que debe marcar todas las clases con los atributos [Serializable]/[DataContract] , pero la experiencia demuestra que, de todos modos, debe hacer algún tipo de ajuste manual, ya que no todos los miembros deberían persistir. También serializa en un Xml, aunque su legibilidad es cuestionable.

Teníamos los mismos requisitos que los suyos y elegimos esta solución.

1

Acepto que los métodos de serialización basados ​​en DataContract (a JSON, XML, etc.) son un poco más complejos de lo que me gustaría.

Si usted está tratando de conseguir JSON echa un vistazo a http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

Es parte de las extensiones de MS AJAX. Es cierto que está marcado como obsoleto en .NET 3.5, pero ScottGu menciona en su comentario del blog aquí (http://weblogs.asp.net/scottgu/archive/2007/10/01/tip-trick-building-a-tojson-extension-method-using-net-3-5.aspx#4301973) que no está seguro de por qué y que debe ser admitido por un tiempo más largo.

Cuestiones relacionadas