Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

attribute not being serialized by XmlSerializer

I'd like to serialize a class to XML, assigning an XML attribute to it. Snippet:

    [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);
        }
    }

But the resulting XML looks like this

<?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>

All well and good, with the only exception being that myClass2.Name is not serialized. I was expecting something in the line of

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

... Why isn't that serialized, and how can it be?

like image 940
user377486 Avatar asked Aug 08 '12 09:08

user377486


People also ask

How does the XmlSerializer work C#?

The XmlSerializer creates C# (. cs) files and compiles them into . dll files in the directory named by the TEMP environment variable; serialization occurs with those DLLs. These serialization assemblies can be generated in advance and signed by using the SGen.exe tool.

Is XmlSerializer thread safe?

Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application.

What is serialization in XML?

XML serialization is the process of converting XML data from its representation in the XQuery and XPath data model, which is the hierarchical format it has in a Db2® database, to the serialized string format that it has in an application.

What is System XML serialization XmlTypeAttribute?

The XmlTypeAttribute belongs to a family of attributes that controls how the XmlSerializer serializes or deserializes an object. For a complete list of similar attributes, see Attributes That Control XML Serialization. You can apply the XmlTypeAttribute to a class, structure, enumeration, or interface declaration.


3 Answers

dont derive List<T>, create class with member 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; }
}
like image 97
burning_LEGION Avatar answered Nov 05 '22 04:11

burning_LEGION


XmlSerializer treats List<> in special way:

XmlSerializer can process classes that implement IEnumerable or ICollection differently if they meet certain requirements. A class that implements IEnumerable must implement a public Add method that takes a single parameter. The Add method's parameter must be consistent (polymorphic) with the type returned from the IEnumerator.Current property returned from the GetEnumerator method. A class that implements ICollection in addition to IEnumerable (such as CollectionBase) must have a public Item indexed property (an indexer in C#) that takes an integer, and it must have a public Count property of type integer. The parameter passed to the Add method must be the same type as that returned from the Item property, or one of that type's bases. For classes implementing ICollection, values to be serialized will be retrieved from the indexed Item property rather than by calling GetEnumerator. Also note that public fields and properties will not be serialized, with the exception of public fields that return another collection class (one that implements ICollection). MSDN - scroll to XML Serialization Considerations

That why it serialized Your class as a list of objects only, without Your property. The best solution is to include List as class public property and mark it as XmlElement.

like image 41
Varius Avatar answered Nov 05 '22 02:11

Varius


Alternative solution: use an array instead of a list and XmlElement

    [XmlType(TypeName = "classmy")]
    public class MyClass2
    {
        [XmlElement(ElementName = "Items")]
        public object[] Items { get; set; }
        [XmlAttribute(AttributeName = "myattr")]
        public string Name { get; set; }
    }
like image 2
user377486 Avatar answered Nov 05 '22 02:11

user377486