sharp serialize serializar net deserialize deserializar c# .net xml-serialization

serializar - serialize list to xml c#



XmlSerialice una colección personalizada con un atributo (5)

Tengo una clase simple que hereda de Collection y agrega un par de propiedades. Necesito serializar esta clase a XML, pero XMLSerializer ignora mis propiedades adicionales.

Supongo que esto se debe al tratamiento especial que XMLSerializer brinda a los objetos ICollection e IEnumerable. ¿Cuál es la mejor manera de evitar esto?

Aquí hay un código de muestra:

using System.Collections.ObjectModel; using System.IO; using System.Xml.Serialization; namespace SerialiseCollection { class Program { static void Main(string[] args) { var c = new MyCollection(); c.Add("Hello"); c.Add("Goodbye"); var serializer = new XmlSerializer(typeof(MyCollection)); using (var writer = new StreamWriter("test.xml")) serializer.Serialize(writer, c); } } [XmlRoot("MyCollection")] public class MyCollection : Collection<string> { [XmlAttribute()] public string MyAttribute { get; set; } public MyCollection() { this.MyAttribute = "SerializeThis"; } } }

Esto genera el siguiente XML (note que MyAttribute falta en el elemento MyCollection):

<?xml version="1.0" encoding="utf-8"?> <MyCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <string>Hello</string> <string>Goodbye</string> </MyCollection>

Lo que quiero es

<MyCollection MyAttribute="SerializeThis" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <string>Hello</string> <string>Goodbye</string> </MyCollection>

¿Algunas ideas? Cuanto más simple, mejor. Gracias.


Las colecciones generalmente no son buenos lugares para las propiedades adicionales. Tanto durante la serialización como en el enlace de datos, se ignorarán si el elemento se ve como una colección ( IList , IEnumerable , etc., según el escenario).

Si fuera yo, encapsularía la colección, es decir,

[Serializable] public class MyCollectionWrapper { [XmlAttribute] public string SomeProp {get;set;} // custom props etc [XmlAttribute] public int SomeOtherProp {get;set;} // custom props etc public Collection<string> Items {get;set;} // the items }

La otra opción es implementar IXmlSerializable (bastante trabajo), pero aún así no funcionará para el enlace de datos, etc. Básicamente, este no es el uso esperado.


He estado peleando con el mismo problema que Romaroo (querer agregar propiedades a la serialización xml de una clase que implementa ICollection). No he encontrado ninguna forma de exponer las propiedades que están en la clase de colección. Incluso intenté usar la etiqueta XmlAttribute y hacer que mis propiedades aparezcan como atributos del nodo raíz, pero tampoco tuve suerte allí. Sin embargo, pude usar la etiqueta XmlRoot en mi clase para cambiarle el nombre desde "ArrayOf ...". Aquí hay algunas referencias en caso de que esté interesado:


Si encapsula, como sugiere Marc Gravell, el comienzo de esta publicación explica cómo hacer que su XML se vea exactamente como usted lo describe.

http://blogs.msdn.com/youssefm/archive/2009/06/12/customizing-the-xml-for-collections-with-xmlserializer-and-datacontractserializer.aspx

Es decir, en lugar de esto:

<MyCollection MyAttribute="SerializeThis" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Items> <string>Hello</string> <string>Goodbye</string> <Items> </MyCollection>

Puedes tener esto:

<MyCollection MyAttribute="SerializeThis" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <string>Hello</string> <string>Goodbye</string> </MyCollection>


Como sugiere Neil Whitaker y en caso de que su enlace muera ...

Cree una colección interna para almacenar las cadenas y aplique el atributo XmlElement para enmascarar el nombre de la colección. Produce el mismo resultado xml que si MyCollection heredó de Collection, pero también serializa atributos en el elemento principal.

[XmlRoot("MyCollection")] public class MyCollection { [XmlAttribute()] public string MyAttribute { get; set; } [XmlElement("string")] public Collection<string> unserializedCollectionName { get; set; } public MyCollection() { this.MyAttribute = "SerializeThis"; this.unserializedCollectionName = new Collection<string>(); this.unserializedCollectionName.Add("Hello"); this.unserializedCollectionName.Add("Goodbye"); } }