Reputation: 152
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
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