2012-08-08 19 views
7

Me gustaría serializar una clase a XML, asignándole un atributo XML. Fragmento:atributo no serializado por XmlSerializer

[XmlType(TypeName = "classmy")] 
    public class MyClass2 : List<object> 
    { 
     [XmlAttribute(AttributeName = "myattr")] 
     public string Name { get; set; } 
    } 

    public class MyConst 
    { 
     public MyConst() 
     { 
      MyClass2 myClass2 = new MyClass2 { 10, "abc" }; 

      myClass2.Name = "nomm"; 

      XmlSerializer serializer = new XmlSerializer(typeof(MyClass2)); 
      serializer.Serialize(Console.Out, myClass2); 
     } 
    } 

Pero el XML resultante es la siguiente

<?xml version="1.0" encoding="IBM437"?> 
<classmy xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <anyType xsi:type="xsd:int">10</anyType> 
    <anyType xsi:type="xsd:string">abc</anyType> 
</classmy> 

Todo esto está muy bien, con la única excepción de que myClass2.Name no es serializado. Esperaba algo en la línea de

<classmy myattr="nomm" [...]>[...]</classmy> 

... ¿Por qué no está serializado y cómo puede ser?

+0

¿Ha decorado con el atributo [Serializable] por encima de su clase? – Rajesh

+0

@Rajesh no habría serializado * en absoluto * si no ... – James

+0

@James Tuve el mismo problema, que él tiene y cuando decoré con serializable resolvió el problema. Especialmente cuando intenta escribir XML. – Rajesh

Respuesta

4

dont derivar List<T>, crear la clase con el miembro List

[XmlType(TypeName = "classmy")] 
public class MyClass2 
{ 
    [XmlAttribute(AttributeName = "Items")] 
    List<object> Items { get; set; } //need to change type in `<>` 

    [XmlAttribute(AttributeName = "myattr")] 
    public string Name { get; set; } 
} 
+0

"No se puede serializar 'elementos' de miembro del tipo System.Object. XmlAttribute/XmlText no se puede usar para codificar tipos complejos." – user377486

+0

es otro problema, lo evita porque el serializador ignora su elemento, debe definir el tipo real para la resolución, es decir, cuerda –

1

solución alternativa: utilizar una matriz en lugar de una lista y XmlElement Lista

[XmlType(TypeName = "classmy")] 
    public class MyClass2 
    { 
     [XmlElement(ElementName = "Items")] 
     public object[] Items { get; set; } 
     [XmlAttribute(AttributeName = "myattr")] 
     public string Name { get; set; } 
    } 
1

trata XmlSerializer <> de manera especial:

XmlSerializer puede procesar clas que implementan IEnumerable o ICollection de forma diferente si cumplen ciertos requisitos. Una clase que implementa IEnumerable debe implementar un método Public Add que tome un solo parámetro. El parámetro del método Add debe ser coherente (polimórfico) con el tipo devuelto por la propiedad IEnumerator.Current devuelta por el método GetEnumerator. Una clase que implemente ICollection además de IEnumerable (como CollectionBase) debe tener una propiedad pública Item indexada (un indexador en C#) que toma un entero, y debe tener una propiedad de Count público de tipo integer. El parámetro pasado al método Agregar debe ser del mismo tipo que el devuelto desde la propiedad Item, o una de las bases de ese tipo. Para las clases que implementan ICollection, los valores que se serializarán se recuperarán de la propiedad indexada de Item en lugar de llamar a GetEnumerator. También tenga en cuenta que los campos públicos y las propiedades no se serializarán, con la excepción de los campos públicos que devuelven otra clase de colección (una que implementa ICollection). MSDN - scroll to XML Serialization Considerations

Por eso serializó Su clase como una lista de objetos solamente, sin Su propiedad. La mejor solución es incluir List como propiedad pública de clase y marcarlo como XmlElement.

Cuestiones relacionadas