Vilo
Vilo

Reputation: 152

C# - XML Deserialization of properties

I cannot find a reason why properties without getters aren't parsing properly, let me write you an example:

For XML in format

<request>
  <job 
     mode="modefirst"
  />
<request>

I am trying to deserialize it to the POCO with a property:

    private ESomeEnum emode;

    [XmlAttribute(AttributeName = "mode")]
    public string Mode
    {
       set { ESomeEnum.TryParse( blah blah );
    }

emode is being set for default value in class constructor, while deserializing (System.Xml.Serialization without custom classes, just trying to be minimalistic in here) the xml from above, the setter is never being called, but when property 'Mode' contains a getter

    get { return this.emode.ToString(); }

setter is actually being hit and proper value set during deserialization.

Why this situation occurs? Is there any reason behind it?

Upvotes: 1

Views: 1041

Answers (1)

Gy&#246;rgy Kőszeg
Gy&#246;rgy Kőszeg

Reputation: 18013

The XmlSerializer processes properties only, which have public get-set accessors. But you can customize anything by implementing IXmlSerializable:

public class MyXmlSerializableClass : IXmlSerializable
{
    private ESomeEnum emode = ESomeEnum.modefirst;

    public string Mode
    {
        set { emode = ESomeEnum.Parse(value); }
    }

    public int ReadWriteProperty { get; set; }

    public int SemiReadOnlyProperty { get; private set; }

    private int backingFieldOfRealReadOnlyProperty;
    public int RealReadOnlyProperty
    {
        get { return backingFieldOfRealReadOnlyProperty; }
    }

    #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {
        if (reader.Settings != null && !reader.Settings.IgnoreWhitespace)
        {
            reader = XmlReader.Create(reader, new XmlReaderSettings { IgnoreWhitespace = true });
            reader.Read();
        }

        reader.ReadStartElement();
        Mode = reader.ReadElementContentAsString("Mode", String.Empty);
        ReadWriteProperty = reader.ReadElementContentAsInt("ReadWriteProperty", String.Empty);
        SemiReadOnlyProperty = reader.ReadElementContentAsInt("ReadOnlyAutoProperty", String.Empty);
        backingFieldOfRealReadOnlyProperty = reader.ReadElementContentAsInt("ReadOnlyProperty", String.Empty);
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("Mode", emode.ToString());
        writer.WriteElementString("ReadWriteProperty", ReadWriteProperty.ToString(CultureInfo.InvariantCulture));
        writer.WriteElementString("ReadOnlyAutoProperty", SemiReadOnlyProperty.ToString(CultureInfo.InvariantCulture));
        writer.WriteElementString("ReadOnlyProperty", RealReadOnlyProperty.ToString(CultureInfo.InvariantCulture));
    }

    #endregion

    internal MyXmlSerializableClass()
    {/*needed for deserialization*/
    }
}

Upvotes: 1

Related Questions