1

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?

1

1 Answer 1

1

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*/
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

So in short the default configuration of the interface is reflecting only ReadWriteProperties, I should take a look at the source first. Thanks for this nice example, I'll use it as a starting point.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.