Can anyone explain how to control the XML generated ?
I have a simple test class, NumberService ...
[Serializable]
public class NumberService
{
public int Number1 { get; set; }
public int Number2 { get; set; }
}
Now if I use an XmlSerializer to deserialise an instance, I get what I expected ...
<NumberService>
<Number1>23</Number1>
<Number2>45</Number2>
</NumberService>
but I was attempting to send this and Fiddler was showing ...
<NumberService>
<_x003C_Number1_x003E_k__BackingField>10</_x003C_Number1_x003E_k__BackingField>
<_x003C_Number2_x003E_k__BackingField>2</_x003C_Number2_x003E_k__BackingField>
</NumberService>
Poking around I've read that this is because of my use of automatic properties, and indeed if I changed to ...
public class NumberService
{
private int _number1;
public int Number1
{
get { return _number1; }
set { _number1 = value; }
}
public int Number2 { get; set; }
}
indeed the XML changes to ...
<NumberService>
<_number1>4</_number1>
<_x003C_Number2_x003E_k__BackingField>6</_x003C_Number2_x003E_k__BackingField>
</NumberService>
But of course I can't change _number1 to Number1 as it'd conflict with the property :-(
So how can you control the XML ?
... and a bit more reading ...
this is involving WCF data contracts
This has to do with how the DataContractSerializer handles items with the Serializable attribute applied.
When confronted with the Serializable attribute, the DataContractSerializer will defer to the semantics that you would expect when using the instance with an IFormatter implementation; in other words, it will serialize the underlying fields using the names of the fields as the keys to the data.
Because you are using auto-generated properties, what you are seeing is actually the names of the auto-generated fields that the compiler generates for you.
In order to get around this, you should apply the DataContract attribute to the class and the DataMember attribute to the properties (and you can control the name by specifying it in the attribute if you want it to differ from the property name).
You also have the option of not specifying the DataContract/DataMember attributes at all and using POCO DataContract serialization; this assumes you have a default parameterless constructor along with only serializing public properties/fields.