Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize class's ToString() value as XmlElement

In C#, I'm trying to serialize ClassA into XML:

[Serializable]
public ClassA 
{
    [XmlElement]
    public string PropertyA { get; set; } // works fine

    [XmlElement]
    public ClassB MyClassB { get; set; }
}

[Serializable]
public ClassB
{
    private string _value;

    public override string ToString()
    {
        return _value;
    }
}

Unfortunately, the serialized result is:

<PropertyA>Value</PropertyA>
<ClassB />

Instead, I want it to be:

<PropertyA>Value</PropertyA>
<ClassB>Test</ClassB>

...assuming _value == "Test". How do I do this? Do I have to provide a public property in ClassB for _value? Thanks!

UPDATE:

By implementing the IXmlSerializable interface in ClassB (shown here #12), the following XML is generated:

<PropertyA>Value</PropertyA>
<ClassB>
    <Value>Test</Value>
</ClassB>

This solution is almost acceptable, but it would be nice to get rid of the tags. Any ideas?

like image 850
Pakman Avatar asked Oct 01 '10 21:10

Pakman


People also ask

What is XmlSerializer C#?

XML serialization is the process of converting an object's public properties and fields to a serial format (in this case, XML) for storage or transport. Deserialization re-creates the object in its original state from the XML output.

Which class should be used to serialize an object in XML format?

Xml. Serialization namespace) class is used to serialize and deserialize. The class method Serialize is called. Since we have to serialize in a file, we create a " TextWriter ".

What is System XML serialization XmlElementAttribute?

The XmlElementAttribute 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.


2 Answers

As you indicated, the only way to do this is to implement the IXmlSerializable interface.

public class ClassB : IXmlSerializable
{
    private string _value;

    public string Value {
        get { return _value; }
        set { _value = value; }
    }

    public override string ToString()
    {
        return _value;
    }

    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        _value = reader.ReadString();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteString(_value);
    }

    #endregion
}

Serializing the following instance...

ClassB classB = new ClassB() { Value = "this class's value" };

will return the following xml :

<?xml version="1.0" encoding="utf-16"?><ClassB>this class's value</ClassB>

You might want to do some validations so that you encode xml tags etc.

like image 56
Peter Avatar answered Oct 02 '22 14:10

Peter


You've answered yourself. if you derive from IXmlSerializable, you can change the method to do exactly (hopefully) what you wish:

    public void WriteXml(System.Xml.XmlWriter writer)
    {
         writer.WriteElementString("ClassB",_value);
    }
like image 40
itsho Avatar answered Oct 02 '22 13:10

itsho